.net 使用Automapper从动态对象复制属性

.net 使用Automapper从动态对象复制属性,.net,dynamic,json.net,automapper,automapper-5,.net,Dynamic,Json.net,Automapper,Automapper 5,我有一个动态对象(实际上是一个JObject,来自JSON.NET)是从JSON动态构建的。 我希望将其属性复制到现有对象。动态对象的属性应该存在于目标对象的类型中,如果不存在,则可以出现错误。 我正在寻找最新版本的Automapper。我试图创建一个从JObject到正确类型的映射,但我认为它不起作用,因为JObject中的属性存储在内部字典中。 这可能吗?是的,这是可能的 如果您已经有了一个JObject,那么您实际上不需要Automapper将属性从它复制到现有的目标对象。Json.Net

我有一个动态对象(实际上是一个JObject,来自JSON.NET)是从JSON动态构建的。 我希望将其属性复制到现有对象。动态对象的属性应该存在于目标对象的类型中,如果不存在,则可以出现错误。 我正在寻找最新版本的Automapper。我试图创建一个从JObject到正确类型的映射,但我认为它不起作用,因为JObject中的属性存储在内部字典中。 这可能吗?

是的,这是可能的

如果您已经有了一个
JObject
,那么您实际上不需要Automapper将属性从它复制到现有的目标对象。Json.Net序列化程序提供了一种方法来实现这一点。您可以创建一个扩展方法,以便直接从
JObject
调用:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public static class JsonExtensions
{
    public static void PopulateObject<T>(this JToken jt, T target)
    {
        JsonSerializer serializer = new JsonSerializer();
        serializer.Populate(jt.CreateReader(), target);
    }
}
下面是一个快速演示来证明这一概念:

如果仍然希望使用Automapper,可以将其配置为执行相同的转换,而不是通常的基于成员的映射。诀窍是在设置映射时使用
ConvertUsing
方法:

Mapper.Initialize(cfg => cfg.CreateMap<JObject, Foo>().ConvertUsing((jo, foo) =>
{
    JsonSerializer serializer = new JsonSerializer();
    serializer.Populate(jo.CreateReader(), foo);
    return foo;
}));
Mapper.Initialize(cfg=>cfg.CreateMap().ConvertUsing((jo,foo)=>
{
JsonSerializer serializer=新的JsonSerializer();
填充(jo.CreateReader(),foo);
返回foo;
}));
然后使用以下代码复制属性:

Mapper.Map<JObject, Foo>(jObj, existingFoo);
Mapper.Map(jObj,existingFoo);

否。。。我明确地说我想把tje属性复制到一个现有的对象上!对不起,我在你的问题中遗漏了那个细节。我已经更新了我的答案。@BrianRogers您已经指出:Json.Net序列化程序提供了一个PopulateObject()方法。。。但实际上,它们提供了Populate()方法。您的答案仍然很清楚,但有点误导。实际上,看起来newtonsoft添加了自己的PopulateObject方法:newtonsoft.Json.JsonConvert.PopulateObject(字符串值,对象目标)@TimFriesen您是对的;我在答案的文本中有错误的方法名称;尽管代码示例是正确的。我修复了它并添加了一个指向文档的链接<代码>JsonSerializer具有
填充功能
JsonConvert
具有
PopulateObject
。区别在于它们接受的参数不同。前者是我们在这里需要的,因为它接受一个
JsonReader
,它可以从
JObject
创建。后者在从JSON字符串开始时使用。
Mapper.Initialize(cfg => cfg.CreateMap<JObject, Foo>().ConvertUsing((jo, foo) =>
{
    JsonSerializer serializer = new JsonSerializer();
    serializer.Populate(jo.CreateReader(), foo);
    return foo;
}));
Mapper.Map<JObject, Foo>(jObj, existingFoo);