使用 Automapper 从动态复制属性
Using Automapper to Copy Properties from a Dynamic
我有一个从 JSON 动态构建的动态对象(实际上是一个 JObject,来自 JSON.NET)。
我想将其属性复制到现有对象。来自动态对象的属性应该存在于目标对象的类型中,如果不存在,则出错是可以的。
为此,我正在查看最新版本的 Automapper。我试图创建一个从 JObject 到正确类型的映射,但我认为它不会起作用,因为 JObject 中的属性存储在内部字典中。
这可能吗?
是的,这是可能的。
如果您已经有一个 JObject
,那么您实际上并不需要 Automapper 将属性从它复制到您现有的目标对象。 Json.Net 序列化程序提供了一个 Populate()
方法来执行此操作。您可以创建一个扩展方法,以便于直接从 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);
}
}
然后,当您需要复制属性时,您可以这样做:
jObj.PopulateObject<Foo>(existingFoo);
注意:如果包含 JObject
的变量被声明为 dynamic
,那么您必须强制转换它以便运行时绑定程序可以找到扩展方法:
((JObject)jObj).PopulateObject<Foo>(existingFoo);
这里有一个快速演示来证明这个概念:https://dotnetfiddle.net/dhPDCj
如果您仍然更喜欢使用 Automapper,您可以将其配置为执行相同的转换,而不是通常的基于成员的映射。诀窍是在设置映射时使用 ConvertUsing
方法:
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);
我有一个从 JSON 动态构建的动态对象(实际上是一个 JObject,来自 JSON.NET)。 我想将其属性复制到现有对象。来自动态对象的属性应该存在于目标对象的类型中,如果不存在,则出错是可以的。 为此,我正在查看最新版本的 Automapper。我试图创建一个从 JObject 到正确类型的映射,但我认为它不会起作用,因为 JObject 中的属性存储在内部字典中。 这可能吗?
是的,这是可能的。
如果您已经有一个 JObject
,那么您实际上并不需要 Automapper 将属性从它复制到您现有的目标对象。 Json.Net 序列化程序提供了一个 Populate()
方法来执行此操作。您可以创建一个扩展方法,以便于直接从 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);
}
}
然后,当您需要复制属性时,您可以这样做:
jObj.PopulateObject<Foo>(existingFoo);
注意:如果包含 JObject
的变量被声明为 dynamic
,那么您必须强制转换它以便运行时绑定程序可以找到扩展方法:
((JObject)jObj).PopulateObject<Foo>(existingFoo);
这里有一个快速演示来证明这个概念:https://dotnetfiddle.net/dhPDCj
如果您仍然更喜欢使用 Automapper,您可以将其配置为执行相同的转换,而不是通常的基于成员的映射。诀窍是在设置映射时使用 ConvertUsing
方法:
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);