2012-05-13 97 views
1

我發現了使用AutoMapper與json.net當反射誤差Automapper反射誤差JObject與Json.Net JObject

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

這裏是目標

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

這裏是映射

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); 
    } 

} 

這裏是(NUnit)單元測試(非空值失敗,空值傳遞)

[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); 
    } 

這裏是例外:

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) 

任何幫助表示讚賞。 謝謝。

+0

您發佈了'SiteSettingMapping'的代碼,但是您使用'SourceTargetMapping'進行測試,是一個錯字嗎?你可以發佈'SourceTargetMappingExtensions.ToRepo'的代碼嗎? – nemesv

+0

我發佈了問題中映射代碼的更新。謝謝 –

回答

0

原來我沒有正確地做映射。我根據AutoMapper的documentation創建了一個自定義類型轉換器,然後運行。

5

我有同樣的問題,只是添加一個明確的映射JObject - > JObject這使克隆。

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

    return new JObject(value); 
});