C# 将平面字典序列化为多子对象JSON

C# 将平面字典序列化为多子对象JSON,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,在C#中,我有一个平面字典,其中键的形式为obj1/obj2/obj3,值为直接字符串。现在我想将其序列化为子对象,因此示例值: var dict = new Dictionary<string, string> { {"foo/bar/baz1", "123" }, {"foo/baz", "456" }, { "foo/abc", "def" } }; 或者,如果可以将输出中的“123”和“456”解释为数字或布尔值,我希望删除它们周围的引号 我使用的是Newtonsoft.J

在C#中,我有一个平面
字典
,其中键的形式为
obj1/obj2/obj3
,值为直接字符串。现在我想将其序列化为子对象,因此示例值:

var dict = new Dictionary<string, string> { {"foo/bar/baz1", "123" }, {"foo/baz", "456" }, { "foo/abc", "def" } };
或者,如果可以将输出中的“123”和“456”解释为数字或布尔值,我希望删除它们周围的引号


我使用的是Newtonsoft.JSON

您可以将源字典解析为using方法。然后遍历所有属性,使用拆分它们并递归地解析到一个新的
JObject
,表示一个属性树。最后,使用将该对象添加到目标对象,或者如果给定的键已经存在,则更新该对象

var dict=newdictionary{{“foo/bar/baz1”、“123”}、{“foo/baz”、“456”}、{“foo/abc”、“def”};
var source=JObject.FromObject(dict);
var dest=new JObject();
foreach(source.Properties()中的var属性)
{
//把名字分成几个部分
var items=property.Name.Split(新[]{”/“},StringSplitOptions.RemoveEmptyEntries);
var item=items.FirstOrDefault();
if(string.IsNullOrEmpty(项))
继续;
//获取表示属性树的JObject
var result=WriteItems(items.Skip(1.ToList(),property.Value);
//检查目标是否已包含顶级属性名称(例如“foo”)
如果(目的地集装箱(项目))
{
(目的[项目]作为作业项目)?。添加(结果第一);
}
其他的
{
目的添加(项目、结果);
}
}
Console.WriteLine(dest.ToString());
//局部函数递归遍历所有属性并创建结果JObject
作业对象写入项(IList项,JToken值)
{
var item=items.FirstOrDefault();
项目移除(0);
如果(!items.Any())//键中没有更多项,请添加值
返回新作业对象(新JProperty(item,value));
返回新作业对象(新JProperty(item,WriteItems,value));
}
它产生以下输出

{
  "foo": {
    "bar": {
      "baz1": "123"
    },
    "baz": "456",
    "abc": "def"
  }
}

此外,上面的代码允许您处理任意深度的属性树。我不认为有一种内置的方法可以将类似于
foo/bar/baz1
的结构序列化为
Json.NET

@PavelAnikhouski中的子对象,使用JsonConverter作为基础,但是在操作键上查找文档比在值上查找文档要困难得多…您可以将属性像那样拆分为多个部分并递归处理,请查看我的答案
{
  "foo": {
    "bar": {
      "baz1": "123"
    },
    "baz": "456",
    "abc": "def"
  }
}