我有一个动态对象(实际上是来自JSON.NET的JObject)是从JSON动态构建的。 我想将其属性复制到现有对象。动态对象的属性应该存在于目标对象的类型中,否则,可以有错误。 我正在研究Automapper,最新版本。我试图从JObject创建一个映射到正确的类型,但我认为它不会起作用,因为JObject中的属性存储在内部字典中。 这有可能吗?
答案 0 :(得分:8)
是的,这是可能的。
如果您已经有JObject
,那么您并不需要Automapper将属性从中复制到现有目标对象。 Json.Net序列化程序提供了一个PopulateObject()
方法来执行此操作。您可以创建一个扩展方法,以便从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);