【问题标题】:Using Automapper to Copy Properties from a Dynamic使用 Automapper 从动态复制属性
【发布时间】:2016-07-15 11:05:21
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    是的,这是可能的。

    如果您已经有一个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);
    

    【讨论】:

    • 不...我明确表示我想将 tje 属性复制到 现有 对象!
    • 对不起,我不知何故错过了您问题中的那个细节。我已经更新了我的答案。
    • @BrianRogers 您曾指出:Json.Net 序列化程序提供了 PopulateObject() 方法......但实际上它们提供了 Populate() 方法。您的答案仍然很清楚,但有点误导。
    • 其实newtonsoft好像加了自己的PopulateObject方法:Newtonsoft.Json.JsonConvert.PopulateObject(string value, object target)
    • @TimFriesen 你是对的;我在答案的文本中使用了错误的方法名称;尽管代码示例是正确的。我修复了它并添加了指向文档的链接。 JsonSerializerPopulateJsonConvertPopulateObject。不同之处在于它们接受的参数。前者是我们这里需要的,因为它接受JsonReader,可以从JObject 创建。当您从 JSON 字符串开始时使用后者。
    猜你喜欢
    • 1970-01-01
    • 2018-09-01
    • 2018-04-06
    • 2012-03-04
    • 2014-10-11
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多