使用Automapper从动态复制属性

时间:2016-07-15 11:05:21

标签: .net dynamic json.net automapper automapper-5

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

1 个答案:

答案 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);