【问题标题】:Deserialize nested JSON into C# objects将嵌套的 JSON 反序列化为 C# 对象
【发布时间】:2016-12-12 02:24:38
【问题描述】:

我从如下所示的 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"]
}

我已经尝试了几种方法来在 c# 对象中表示这个 JSON(这里列出的太多了)。我尝试过使用列表和字典,这是我最近尝试表示的示例:

    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; }
    }

这是我用来反序列化 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 包含 ItemsErrors。而Items 包含SubItems,但SubItemsnull。因此,除了Errors 之外,实际上没有任何东西被反序列化。

应该很简单,但由于某种原因我无法找出正确的对象表示

【问题讨论】:

    标签: c# json json.net deserialization json-deserialization


    【解决方案1】:

    使用此站点进行表示:

    https://quicktype.io/csharp/

    这样的事情可能会对你有所帮助

    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; }
    }
    

    这里是如何反序列化(使用 JsonConvert 类):

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

    【讨论】:

    • Item322A 和 Item2B 不是常量。不过谢谢你的回答
    • 作为对此感兴趣的任何人的后续行动。如果您使用 Visual Studio,则可以使用“选择性粘贴”功能。并且基本上与此答案中的链接站点相同。也适用于 XML
    【解决方案2】:

    对于"Items",使用Dictionary&lt;string, List&lt;Info&gt;&gt;,即:

    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; }
    }
    

    这假定项目名称 "Item322A""Item2B" 会因响应而异,并将这些名称作为字典键读取。

    示例fiddle

    【讨论】:

    • 酷,我要试试这个。我只是尝试了一种类似的方法,但是将字典包含在一个列表中!
    • 这行得通。原来我的最后一次尝试是如此接近
    【解决方案3】:

    您可以使用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);
    }}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 2017-12-28
      • 2017-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多