简体   繁体   English

将嵌套的 JSON 反序列化为 C# 对象

[英]Deserialize nested JSON into C# objects

I am getting JSON back from an API that looks like this:我从如下所示的 API 中获取 JSON:

{
  "Items": {
    "Item322A": [{
      "prop1": "string",
      "prop2": "string",
      "prop3": 1,
      "prop4": false
    },{
      "prop1": "string",
      "prop2": "string",
      "prop3": 0,
      "prop4": false
    }],
       "Item2B": [{
      "prop1": "string",
      "prop2": "string",
      "prop3": 14,
      "prop4": true
    }]
  },
  "Errors": ["String"]
}

I have tried a few approaches to represent this JSON in c# objects (too many to list here).我尝试了几种方法来在 c# 对象中表示这个 JSON(太多了,无法在此列出)。 I've tried with lists and dictionaries, here is a recent example of how I've tried to represent it:我尝试过使用列表和字典,这是我最近尝试表示它的一个例子:

    private class Response
    {
        public Item Items { get; set; }
        public string[] Errors { get; set; }
    }

    private class Item
    {
        public List<SubItem> SubItems { get; set; }
    }

    private class SubItem
    {
        public List<Info> Infos { get; set; }
    }

    private class Info
    {
        public string Prop1 { get; set; }
        public string Prop2 { get; set; }
        public int Prop3 { get; set; }
        public bool Prop4 { get; set; }
    }

And here is the method I am using to deserialize the JSON:这是我用来反序列化 JSON 的方法:

    using (var sr = new StringReader(responseJSON))
    using (var jr = new JsonTextReader(sr))
    {
        var serial = new JsonSerializer();
        serial.Formatting = Formatting.Indented;
        var obj = serial.Deserialize<Response>(jr);
    }

obj contains Items and Errors . obj包含ItemsErrors And Items contains SubItems , but SubItems is null .并且Items包含SubItems ,但SubItemsnull So nothing except for Errors is actually getting deserialized.因此,除了Errors之外,实际上没有任何东西被反序列化。

It should be simple, but for some reason I can't figure out the correct object representation它应该很简单,但由于某种原因我无法弄清楚正确的对象表示

Use this this site for representation:使用此站点作为代表:

https://quicktype.io/csharp/ https://quicktype.io/csharp/

something like this may help you像这样的事情可能会帮助你

public class Item322A
{
    public string prop1 { get; set; }
    public string prop2 { get; set; }
    public int prop3 { get; set; }
    public bool prop4 { get; set; }
}

public class Item2B
{
    public string prop1 { get; set; }
    public string prop2 { get; set; }
    public int prop3 { get; set; }
    public bool prop4 { get; set; }
}

public class Items
{
    public List<Item322A> Item322A { get; set; }
    public List<Item2B> Item2B { get; set; }
}

public class jsonObject
{
    public Items Items { get; set; }
    public List<string> Errors { get; set; }
}

Here is how to deserialize (use JsonConvert class):以下是反序列化的方法(使用 JsonConvert 类):

jsonObject ourlisting = JsonConvert.DeserializeObject<jsonObject>(strJSON);

For "Items" use a Dictionary<string, List<Info>> , ie:对于"Items"使用Dictionary<string, List<Info>> ,即:

class Response
{
    public Dictionary<string, List<Info>> Items { get; set; }
    public string[] Errors { get; set; }
}

class Info
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public int Prop3 { get; set; }
    public bool Prop4 { get; set; }
}

This assumes that the item names "Item322A" and "Item2B" will vary from response to response, and reads these names in as the dictionary keys.这假设项目名称"Item322A""Item2B"会因响应而异,并将这些名称作为字典键读入。

Sample fiddle .样品小提琴

You could use Json.Parse so that you can query into the data -- and just use the single model.您可以使用Json.Parse以便您可以查询数据——并且只使用单个模型。

private class Info
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public int Prop3 { get; set; }
    public bool Prop4 { get; set; }
}

var result = JObject.Parse(resultContent);   //parses entire stream into JObject, from which you can use to query the bits you need.
var items = result["Items"].Children().ToList();   //Get the sections you need and save as enumerable (will be in the form of JTokens)

List<Info> infoList = new List<Info>();  //init new list to store the objects.

//iterate through the list and match to an object. If Property names don't match -- you could also map the properties individually. Also useful if you need to dig out nested properties.
foreach(var subItem in items){
foreach(JToken result in subItem){
Info info = result.ToObject<Info>();
infoList.add(info);
}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM