Mapping to/from Newtonsoft.Json.Linq objects

1,612 views
Skip to first unread message

Michael Powell

unread,
Sep 6, 2016, 1:30:25 PM9/6/16
to automapp...@googlegroups.com
Hello,

Curious, does anyone do any conversions to/from Newtonsoft.Json.Linq?

I am making it work via AutoMapper TypeConverter, but I wondered if it
might work just as well via the IMapperConfiguration CreateMap
methods?

The only snags I can think of there is that there don't appear to be
any parameterless ctors, for instance. Then what to do about naming
properties, etc.

But besides that...

Just curious.

Thanks!

Regards,

Michael Powell

Jimmy Bogard

unread,
Sep 6, 2016, 1:50:36 PM9/6/16
to automapper-users
Hmmmm, I don't think so. Thought I don't know what it is.....what is it?


--
You received this message because you are subscribed to the Google Groups "AutoMapper-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to automapper-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

vinni...@gmail.com

unread,
Sep 6, 2016, 6:52:17 PM9/6/16
to AutoMapper-users
Hi Michael, Jimmy,

I was about to start a separate thread, but it seems right in line with this one:

I used to do this in AutoMapper 4 just fine, but I've run into an issue in AutoMapper 5.

UserProfileDTO.Properties is of type JObject.
UserProfile.Properties is a string.

                        Mapper.CreateMap<Entities.UserProfile, UserProfileDTO>()
                .ForMember(dest => dest.Properties, ops => ops.MapFrom(src => src.Properties == null ? new JObject() : JObject.Parse(src.Properties)))
                .ForMember(dest => dest.Companies, opts => opts.ResolveUsing<CompanyIDsResolver>())
                .ForMember(dest => dest.User, opts => opts.ResolveUsing<UserEmailResolver>());



This could would work just fine in AutoMapper 4, but in AutoMapper 5 it breaks at Mapper initialization with the following:
System.ArgumentException was unhandled by user code
  HResult=-2147024809
  Message=Instance property 'Key' is not defined for type 'Newtonsoft.Json.Linq.JToken'
  Source=System.Core
  StackTrace:
       at System.Linq.Expressions.Expression.Property(Expression expression, String propertyName)
       at AutoMapper.Mappers.CollectionMapperExtensions.MapKeyPairValueExpr(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Type sourceType, Type destType, ParameterExpression itemParam, Expression contextParam)
       at AutoMapper.Mappers.CollectionMapperExtensions.MapCollectionExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression, Func`2 conditionalExpression, Type ifInterfaceType, MapItem mapItem)
       at AutoMapper.Mappers.DictionaryMapper.MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression)
       at AutoMapper.Execution.TypeMapPlanBuilder.MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, TypePair typePair, Expression sourceParameter, Expression contextParameter, PropertyMap propertyMap, Expression destinationParameter)
       at AutoMapper.Execution.TypeMapPlanBuilder.CreatePropertyMapFunc(PropertyMap propertyMap)
       at AutoMapper.Execution.TypeMapPlanBuilder.TryPropertyMap(PropertyMap propertyMap)
       at AutoMapper.Execution.TypeMapPlanBuilder.CreateAssignmentFunc(Expression destinationFunc, Boolean constructorMapping)
       at AutoMapper.Execution.TypeMapPlanBuilder.CreateMapperLambda()
       at AutoMapper.TypeMap.Seal(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider)
       at AutoMapper.Execution.TypeMapPlanBuilder.MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, TypePair typePair, Expression sourceParameter, Expression contextParameter, PropertyMap propertyMap, Expression destinationParameter)
       at AutoMapper.Execution.TypeMapPlanBuilder.CreatePropertyMapFunc(PropertyMap propertyMap)
       at AutoMapper.Execution.TypeMapPlanBuilder.TryPropertyMap(PropertyMap propertyMap)
       at AutoMapper.Execution.TypeMapPlanBuilder.CreateAssignmentFunc(Expression destinationFunc, Boolean constructorMapping)
       at AutoMapper.Execution.TypeMapPlanBuilder.CreateMapperLambda()
       at AutoMapper.TypeMap.Seal(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider)
       at AutoMapper.MapperConfiguration.Seal(IConfiguration configuration)
       at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression, IEnumerable`1 mappers)
       at AutoMapper.Mapper.Initialize(Action`1 config)
... OMITTED for security ...
  InnerException: 


I'm not sure what's going on here because it seems to be deep in the bowels of AutoMapper.  It's preventing me from upgrading, though, so it looks like I'm going to be on v4 for the time being.  Let me know if you have any insights, thanks!

Vinnie


On Tuesday, September 6, 2016 at 10:50:36 AM UTC-7, Jimmy Bogard wrote:
Hmmmm, I don't think so. Thought I don't know what it is.....what is it?
On Tue, Sep 6, 2016 at 12:30 PM, Michael Powell <mwpow...@gmail.com> wrote:
Hello,

Curious, does anyone do any conversions to/from Newtonsoft.Json.Linq?

I am making it work via AutoMapper TypeConverter, but I wondered if it
might work just as well via the IMapperConfiguration CreateMap
methods?

The only snags I can think of there is that there don't appear to be
any parameterless ctors, for instance. Then what to do about naming
properties, etc.

But besides that...

Just curious.

Thanks!

Regards,

Michael Powell

--
You received this message because you are subscribed to the Google Groups "AutoMapper-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to automapper-use...@googlegroups.com.

Michael Powell

unread,
Sep 7, 2016, 7:00:43 PM9/7/16
to AutoMapper-users, vinni...@gmail.com


On Tuesday, September 6, 2016 at 6:52:17 PM UTC-4, vinni...@gmail.com wrote:
Hi Michael, Jimmy,

I was about to start a separate thread, but it seems right in line with this one:

I used to do this in AutoMapper 4 just fine, but I've run into an issue in AutoMapper 5.

UserProfileDTO.Properties is of type JObject.
UserProfile.Properties is a string.

I end up with a mapping something like this:

cfg.CreateMap<IEnumerable<Roster>, string>()
    .ConvertUsing<RosterEnumerationToJsonStringTypeConverter>();

Which RosterEnumerationToJsonStringTypeConverter implements TypeConverter, with some other interfaces and C# constraints involved, but basically that's it.

As the name suggests, I convert it to a JArray of Roster JObject(s), which I convert to a Json string. Which, in my estimation, also has the potential to save at least one dependency on Newtonsoft.Json.Whatever in my actual Controller code.

This seems to work really well, and I have control over the names of the JProperty(ies), etc. I gets a little tedious decomposing the conversion from model to Json but not so much so it is unmanageable.
 

                        Mapper.CreateMap<Entities.UserProfile, UserProfileDTO>()
                .ForMember(dest => dest.Properties, ops => ops.MapFrom(src => src.Properties == null ? new JObject() : JObject.Parse(src.Properties)))
                .ForMember(dest => dest.Companies, opts => opts.ResolveUsing<CompanyIDsResolver>())
                .ForMember(dest => dest.User, opts => opts.ResolveUsing<UserEmailResolver>());



This could would work just fine in AutoMapper 4, but in AutoMapper 5 it breaks at Mapper initialization with the following:

At the same time, I was wondering how difficult it might be to establish a mapping along these similar lines, but for the lack of Newtonsoft.Json ctors.

I haven't upgraded to AutoMapper v5+ yet; I'm still on v4.2.1.
Reply all
Reply to author
Forward
0 new messages