【问题标题】:Convert delimited string to Expando Object将分隔字符串转换为 Expando 对象
【发布时间】:2020-02-28 21:59:55
【问题描述】:

我有一本这样的字典 -

Dictionary<string, Object> dict = new Dictionary<string, Object>();
dict.Add("event.data", "data");
dict.Add("event.Location", LocObj);
dict.Add("event.Details.Cost", CostObj);

我正在尝试将其与现有的 json 结构合并 -

{
   "event" : {
       "name" : "Hello World",
       "tags" : [tags]
    }
    "sponsors" : {
       ...
    }
    "OtherObj" : {
       ...
    }
 }

我正在尝试使用 ExpandoObject,然后将其注入到原始 json 中,就像这样-

 foreach(KeyValuePair<string, Object> kvp in dict) {            

        var newObj= new ExpandoObject() as IDictionary<string, Object>;
        newObj.Add(kvp.Key, value);         

        existingObject.Merge(JObject.FromObject(newObj), new JsonMergeSettings
        {
            MergeArrayHandling = MergeArrayHandling.Union
        });
    }

   Console.WriteLine(JsonConvert.SerializeObject(existingObject));  

但是当它被序列化时,event.Location 不会显示在现有的事件标签中,而是添加一个名为 event.Location 的新键。

{
   "event" : {
       "name" : "Hello World",
       "tags" : [tags]
    },
    "event.Location" : { ... },   <---------------
    "event.data": { ... },        <---------------        
    "event.Details.Cost" : { ... }<---------------        
    "sponsors" : {
       ...
    },
    "OtherObj" : {
       ...
    }
 }

如何修复 Expando obj 创建以解决此问题?

【问题讨论】:

  • 键,在 JSON 术语以及 JavaScript 对象术语中,可以是任何字符串,包括其中带有点的字符串。如果您想要 event 对象上的新属性,则需要构建它。我建议使用动态对象,例如 var newObj = new { event = new { Location = LocObj, Details = new { Cost = CostObj } } }
  • @HereticMonkey 我从不同的开发人员那里得到字典,它是动态的。我一直在寻找一种通用的方法来实现这一点并合并所有属性。
  • 什么是existingObject?
  • @ZakkDiaz 这只是 JObject existingObject= JObject.FromObject(myobject); .. MyObject 包含我在第一个 Json 中粘贴的所有字段..
  • MyObject 是任意/动态类型吗?还是已知类型?

标签: c# .net json json.net expandoobject


【解决方案1】:

请参阅以下程序。这将显示一个工作合并和中断合并的示例。不同之处在于对象的结构。在一种情况下,“Event.Location”不起作用。在另一种情况下,“事件”对象包含一个“位置”,它正确嵌套在 JObject 的合并操作中。

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Dynamic;

namespace DynamicSerial
{
    class Program
    {
        static void Main(string[] args)
        {
            var myObject = new Dictionary<string, Object>();
            myObject.Add("Id", 1);
            myObject.Add("Event", new { Name = "SomeName", Id = 2 });

            var mergeObject = new Dictionary<string, Object>();
            mergeObject.Add("Event", new { Location = new { Name = "SomeLocation", Id = 3 } }); //WORKS
            //mergeObject.Add("Event.Location", new { Name = "SomeLocation", Id = 3 }); //DOES NOT WORK

            JObject myDynamicObject = JObject.FromObject(myObject);

            foreach (KeyValuePair<string, Object> kvp in mergeObject)
            {

                var newObj = new ExpandoObject() as IDictionary<string, Object>;
                newObj.Add(kvp.Key, kvp.Value);

                myDynamicObject.Merge(JObject.FromObject(newObj), new JsonMergeSettings
                {
                    MergeArrayHandling = MergeArrayHandling.Merge
                });
            }

            Console.WriteLine(JsonConvert.SerializeObject(myDynamicObject));

        }
    }
}

生成的 JSON

good:
{"Id":1,"Event":{"Name":"SomeName","Id":2,"Location":{"Name":"SomeLocation","Id":3}}}
bad:
{"Id":1,"Event":{"Name":"SomeName","Id":2},"Event.Location":{"Name":"SomeLocation","Id":3}}

总之,你应该改变

Dictionary<string, Object> dict = new Dictionary<string, Object>();
dict.Add("event.data", "data");
dict.Add("event.Location", LocObj);
dict.Add("event.Details.Cost", CostObj);

Dictionary<string, Object> dict = new Dictionary<string, Object>();
dict.Add("event", new { data="data", Location=LocObj, Details=new { Cost=CostObj } });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 2013-05-06
    • 2021-06-26
    • 2021-12-03
    • 1970-01-01
    • 2011-12-15
    • 2019-08-23
    相关资源
    最近更新 更多