使用Newtonsoft.JSON解析动态JSON在反序列化对象中缺少数组

时间:2016-04-07 02:34:06

标签: c# json.net expandoobject

当我到达第三个循环时,它会爆炸,因为它无法在桌面上找到“行”。为什么呢?

var converter = new ExpandoObjectConverter();
dynamic deserializeObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);

foreach (var model in deserializeObject.Model)
{
    foreach (var table in model.Table)
    {
        foreach (var row in table.Row)
        {
            Console.WriteLine(row.BookId + ": " + row.BookName);
        }
    }
}

JSON:

{
  "Model": [
    {
      "Field1": "Field1Value",
      "Field2": "Field2Value",
      "Field3": "Field3Value",
      "Table": {
        "Row": [
          {
            "BookId": "1",
            "BookName": "Computer Architecture",
            "Category": "Computers",
            "Price": "125.60"
          },
          {
            "BookId": "2",
            "BookName": "Asp.Net 4 Blue Book",
            "Category": "Programming",
            "Price": "56.00"
          },
          {
            "BookId": "3",
            "BookName": "Popular Science",
            "Category": "Science",
            "Price": "210.40"
          },
          {
            "BookId": "4",
            "BookName": "Mission Impossible",
            "Category": "Adventure",
            "Price": "210.40"
          }
        ]
      }
    },
    {
      "ClientFirstName": "Jane",
      "ClientLastName": "Doe",
      "Table": [
        {
          "Row": [
            {
              "BookId": "1",
              "BookName": "Computer Architecture",
              "Category": "Computers",
              "Price": "125.60"
            },
            {
              "BookId": "3",
              "BookName": "Popular Science",
              "Category": "Science",
              "Price": "210.40"
            },
            {
              "BookId": "4",
              "BookName": "Mission Impossible",
              "Category": "Adventure",
              "Price": "210.40"
            }
          ]
        },
        {
          "Row": [
            {
              "BookId": "1",
              "BookName": "Computer Architecture",
              "Category": "Computers",
              "Price": "125.60"
            },
            {
              "BookId": "4",
              "BookName": "Mission Impossible",
              "Category": "Adventure",
              "Price": "210.40"
            }
          ]
        }
      ]
    }
  ]
}

2 个答案:

答案 0 :(得分:2)

问题不在于您反序列化对象的方式。您的json在包含表的两个对象之间是不同的。

第一个对象是一个包含行数组的表:

    "Table": {
    "Row": [
      {
        "BookId": "1",
        "BookName": "Computer Architecture",
        "Category": "Computers",
        "Price": "125.60"
      },
      {
        "BookId": "2",
        "BookName": "Asp.Net 4 Blue Book",
        "Category": "Programming",
        "Price": "56.00"
      },
      {
        "BookId": "3",
        "BookName": "Popular Science",
        "Category": "Science",
        "Price": "210.40"
      },
      {
        "BookId": "4",
        "BookName": "Mission Impossible",
        "Category": "Adventure",
        "Price": "210.40"
      }
    ]
  }
}

你的第二个客户端对象有一个数组数组。此外,在表数组之外的客户端对象中有第二行数组。

       "Table": [
    {
      "Row": [
        {
          "BookId": "1",
          "BookName": "Computer Architecture",
          "Category": "Computers",
          "Price": "125.60"
        },
        {
          "BookId": "3",
          "BookName": "Popular Science",
          "Category": "Science",
          "Price": "210.40"
        },
        {
          "BookId": "4",
          "BookName": "Mission Impossible",
          "Category": "Adventure",
          "Price": "210.40"
        }
      ]
    },
    {
      "Row": [
        {
          "BookId": "1",
          "BookName": "Computer Architecture",
          "Category": "Computers",
          "Price": "125.60"
        },
        {
          "BookId": "4",
          "BookName": "Mission Impossible",
          "Category": "Adventure",
          "Price": "210.40"
        }
      ]
    }

我建议不同地格式化你的json,或者创建一个不同的方法来循环你在json中的两种类型的表。一个是对象,另一个是数组。

例如。我将您的动态更改为Newtonsoft.Json.Linq中的Newtonsoft Jobject;这将选择两个表,一个是对象,第二个是数组。

       var converter = new ExpandoObjectConverter();
        var deserializeObject = JsonConvert.DeserializeObject<JObject>(jsonString, converter);

        foreach(var v in deserializeObject["Model"])
        {
            if(v["Table"] != null && v["Table"].Type == JTokenType.Object)
            {
                foreach (var x in v["Table"]["Row"])
                {
                    Console.Write(x["BookId"] + " : " + x["BookName"] + Environment.NewLine);
                }
            }
            else if (v["Table"].Type == JTokenType.Array)
            {
                foreach(var subTable in v["Table"])
                {
                    foreach (var row in subTable["Row"])
                    {
                        Console.Write(row["BookId"] + " : " + row["BookName"] + Environment.NewLine);
                    }
                }

            }              
        }

答案 1 :(得分:1)

JSON中的

Table属性在一个实例中被格式化为数组,在另一个实例中被设置为对象。前者反序列化为List<object>,而后者反序列化为KeyValuePair<string, object>

您可以检查当前实例中的Table是否为KeyValuePair<string, object>类型,然后相应地继续:

foreach (var model in deserializeObject.Model)
{
    foreach (var table in model.Table)
    {
        if(table is KeyValuePair<string, object>)
        {
            foreach (var row in table.Value)
            {
                Console.WriteLine(row.BookId + ": " + row.BookName);
            }
        }
        else
        {
            foreach (var row in table.Row)
            {
                Console.WriteLine(row.BookId + ": " + row.BookName);
            }
        }
    }
}

<强> dotnetfiddle demo