如何使用 C# 创建一个复杂的 JSON 对象

jas*_*son 1 c# json

我有这样一个 JSON 结构:

{
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "size": 3938},
      {"name": "MergeEdge", "size": 743}
     ]
    },
    {
     "name": "graph",
     "children": [
      {"name": "BetweennessCentrality", "size": 3534},
      {"name": "SpanningTree", "size": 3416}
     ]
    },
    {
     "name": "optimization",
     "children": [
      {"name": "AspectRatioBanker", "size": 7074}
     ]
    }
   ]
  },
  {
   "name": "animate",
   "children": [
    {"name": "Easing", "size": 17010},
    {"name": "FunctionSequence", "size": 5842},
    {
     "name": "interpolate",
     "children": [
      {"name": "ArrayInterpolator", "size": 1983},
      {"name": "RectangleInterpolator", "size": 2042}
     ]
    },
    {"name": "ISchedulable", "size": 1041},
    {"name": "Tween", "size": 6006}
   ]
  }
 ]
}
Run Code Online (Sandbox Code Playgroud)

如何使用 C# 生成这样的 JSON,我发现了如何制作 JSON 数组,但这就是我所拥有的。我不知道如何制作children":属性,或者我不知道如何制作由其他 JSON 对象或其他 JSON 数组组成的 JSON 对象。你能给我一点动力,让我可以生成这样一个 JSON 对象吗?谢谢。

Dmi*_*rov 6

使用匿名类型,您可以定义对象层次结构,几乎与使用纯 JSON 一样简单。然后使用Json.Net序列化它:

var obj = new {
    name = "flare",
    children = new[] {
        new { name = "analytics" },
        new { name = "animate" },
    }
};
var json = JsonConvert.SerializeObject(obj, Formatting.Indented);
Run Code Online (Sandbox Code Playgroud)

对于更复杂的层次结构,您可能需要涉及动态类型。这是你的原始对象:

var obj = new {
    name = "flare",
    children = new[] {
        new {
            name = "analytics",
            children = new dynamic [] {
                new {
                    name = "cluster",
                    children = new dynamic [] {
                        new { name = "AgglomerativeCluster", size = 3938},
                        new { name = "MergeEdge", size = 743},
                    }
                },
                new {
                    name = "graph",
                    children = new dynamic [] {
                        new { name = "BetweennessCentrality", size = 3534},
                        new { name = "SpanningTree", size = 3416},
                    }
                },
                new {
                    name = "optimization",
                    children = new dynamic [] {
                        new { name = "AspectRatioBanker", size = 7074},
                    }
                },
            }
        },
        new {
            name = "animate",
            children = new dynamic [] {
                new { name = "Easing", size = 17010},
                new { name = "FunctionSequence", size = 5842},
                new {
                    name = "interpolate",
                    children = new [] {
                    new { name = "ArrayInterpolator",  size = 1983},
                    new { name = "RectangleInterpolator", size = 2042}
                    }
                },
                new { name = "ISchedulable", size = 1041},
                new { name = "Tween", size = 6006},
            }
        },
    }
};
var json = JsonConvert.SerializeObject(obj, Formatting.Indented);
Run Code Online (Sandbox Code Playgroud)

演示: https: //dotnetfiddle.net/u2HIt3


Mat*_*and 5

如果你使用Json.Net(你应该使用),你可以创建一个这样的类:

public class MyObject
{   
    public string Name { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public List<MyObject> Children { get; set; }
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public int? Size { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,如果你创建你的对象是这样(我没有做这件事,只是几级-显然你不具有填充,一次就全部):

var root = new MyObject() 
{
    Name = "flare",
    Children = new List<MyObject>() 
    {
        new MyObject()
        {
            Name = "analytics",
            Children = new List<MyObject>() 
            {
                new MyObject()
                {
                    Name = "cluster",
                    Children = new List<MyObject>() 
                    {
                        new MyObject() { Name = "AgglomerativeCluster", Size = 3938 }
                    }
                }
            }
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

进而:

var json = JsonConvert.SerializeObject(root, new JsonSerializerSettings 
{ 
    ContractResolver = new CamelCasePropertyNamesContractResolver()
}));
Run Code Online (Sandbox Code Playgroud)

这会给你(为了可读性,事后格式化):

{
    "name": "flare",
    "children": [{
        "name": "analytics",
        "children": [{
            "name": "cluster",
            "children": [{
                "name": "AgglomerativeCluster",
                "size": 3938
            }]
        }]
    }]
}
Run Code Online (Sandbox Code Playgroud)

一些注意事项:

NullValueHandling = NullValueHandling.Ignore允许您禁止包含值为 null 的属性。如果你不关心Name = "flare"有一个的对象size: null,那么你就不用担心它。但是如果你这样做了,使用它可以节省至少三个不同的对象,这些对象基本相同但缺少一些属性。

CamelCasePropertyNamesContractResolver将自动使用驼峰式大小写您的属性名称。您可以将属性设置MyObject为驼峰式,但这不是 .NET 标准。如果您可以打破该约定,那么您就不需要它。另一种选择是PropertyNameJsonPropertyAttributefor each .NET 属性中进行设置。