使用自动映射器从动态对象复制属性 [英] Using Automapper to Copy Properties from a Dynamic

查看:119
本文介绍了使用自动映射器从动态对象复制属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个动态对象(实际上是JSON.NET的JObject),它是根据JSON动态生成的. 我想将其属性复制到现有对象.动态对象的属性应该存在于目标对象的类型中,如果没有,则可以有一个错误. 我正在为此寻找最新版本的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);

I have a dynamic object (actually, a JObject, from JSON.NET) being built dynamically from JSON. I want to have its properties copied to an existing object. The properties from the dynamic object should exist in the target object's type, if not, it's ok to have an error. I am looking at Automapper, latest version, for this. I tried to create a map from JObject to the proper type, but I don't think it'll work because the properties in the JObject are stored in an internal dictionary. Is this possible at all?

解决方案

Yes, this is possible.

If you already have a JObject, then you don't really need Automapper to copy the properties from it to your existing target object. The Json.Net serializer provides a Populate() method which will do this. You can create an extension method to make it easy to call right from the 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);
    }
}

Then, whenever you need to copy the properties you can do this:

jObj.PopulateObject<Foo>(existingFoo);

Note: if your variable that holds the JObject is declared as dynamic then you'll have to cast it so the runtime binder can find the extension method:

((JObject)jObj).PopulateObject<Foo>(existingFoo);

Here is a quick demo to prove the concept: https://dotnetfiddle.net/dhPDCj

If you would still prefer to use Automapper, you can configure it to do this same conversion instead of its usual member-based mapping. The trick is to use the ConvertUsing method when setting up the mapping:

Mapper.Initialize(cfg => cfg.CreateMap<JObject, Foo>().ConvertUsing((jo, foo) =>
{
    JsonSerializer serializer = new JsonSerializer();
    serializer.Populate(jo.CreateReader(), foo);
    return foo;
}));

Then use this code to copy the properties:

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

这篇关于使用自动映射器从动态对象复制属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆