使用 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);