4

I'm getting a reflection error when using AutoMapper with a json.net JObject

public class Source
{
    public string Key { get; set; }
    public JObject Value { get; set; }
}

Here is the target

public class Target
{
    public string Key { get; set; }
    public JObject Value { get; set; }
}

Here is the mapping

public class SourceTargetMapping
{
    public static void IntializeMapping()
    {
        Mapper.CreateMap<Target, Source>()
            .ForMember(g => g.Value, op => op.ResolveUsing(s => s.Value));

        Mapper.CreateMap<Source, Target>()
            .ForMember(s => s.Value, op => op.ResolveUsing(g => g.Value));
    }

}

public static class SourceTargetMappingExtensions
{
    public static Source ToDomain(this Target repoItem)
    {
        var result = Mapper.Map<Target, Source>(repoItem);
        return result;
    }

    public static Target ToRepo(this Source domainItem)
    {
        var result = Mapper.Map<Source, Target>(domainItem);
        return result;
    }

    public static List<Source> ToDomain(this ICollection<Target> repoCollection)
    {
        return Mapper.Map<ICollection<Target>, List<Source>>(repoCollection);
    }

    public static List<Target> ToRepo(this ICollection<Source> domainCollection)
    {
        return Mapper.Map<ICollection<Source>, List<Target>>(domainCollection);
    }

}

Here is the (NUnit) unit test (the ones with non empty values fail, empty values pass)

[TestFixture]
public class AutoMappingTest
{
  [SetUp]
  public void SetUp()
  {
    SourceTargetMapping.IntializeMapping();
    Mapper.AssertConfigurationIsValid();
  }

  [TestCase("State", "{\"State\":\"TX\"}", "Should handle normal value")]
  [TestCase("State", @"{""State"":""TX""}", "double quoted quotes")]
  [TestCase("State", "", "empty json")]
  [TestCase("State", null, "null json")]
  public void ShouldMapFromSourceToTarget(string key, string value, string description)
  {
    //arrange
    JObject jObject = (!string.IsNullOrEmpty(value)) ? JObject.Parse(value) : new JObject();
    var source = new Source() {Key = key, Value = jObject};

    //act
    var repo = source.ToRepo();

    Assert.IsNotNull(repo);
    Assert.AreEqual(key, repo.Key);
  }

And here is the exception:

AutoMapper.AutoMapperMappingException : 

Mapping types:
JObject -> JObject
Newtonsoft.Json.Linq.JObject -> Newtonsoft.Json.Linq.JObject

Destination path:
Target.Value

Source value:
{
  "State": "TX"
}
  ----> System.Reflection.TargetException : Object does not match target type.
at IsolationChamber.SourceTargetMappingExtensions.ToRepo(Source domainItem) in SourceTargetMapping.cs: line 62
at IsolationChamberTest.AutoMappingTest.ShouldMapFromSourceToTarget(String key, String value, String description) in AutoMapperSiteSettingTest.cs: line 35
--TargetException
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at AutoMapper.Mappers.DictionaryMapper.Map(ResolutionContext context, IMappingEngineRunner mapper)
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) 

Any help is appreciated. Thank you.

2
  • You posted the code of SiteSettingMapping but your test using SourceTargetMapping, is it a typo? And can you post the code for SourceTargetMappingExtensions.ToRepo? Commented May 13, 2012 at 15:55
  • I posted an update to the mapping code in the question. thanks Commented May 13, 2012 at 16:10

2 Answers 2

8

I had the same issue, just add an explicit mapping JObject -> JObject which makes a clone.

Mapper.CreateMap<JObject, JObject>().ConvertUsing(value =>
{
    if (value == null)
        return null;

    return new JObject(value);
});
Sign up to request clarification or add additional context in comments.

Comments

0

It turns out I was not doing the mapping correctly. I created a custom type converter per AutoMapper's documentation and then it worked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.