2016-04-07 4 views
0

Когда я добираюсь до третьего цикла, он взрывается, потому что он не может найти «Строка» на столе. Зачем?Разбор динамического JSON с Newtonsoft.JSON отсутствует массив в десериализованном объекте

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" 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 
+0

проверить в JSON http://jsonlint.com/ – tofutim

+0

Код переформатирован – Thomas

ответ

1

Table свойство в вашем JSON отформатирована как массив в одном экземпляре и в качестве объекта в другой. Бывший десериализуется до 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

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 Jobject, который находится в Newtonsoft.Json.Linq; Это будет отображаться на обеих таблицах, один из которых является объектом, а второй - массивом.

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

      }    
     } 

 Смежные вопросы

  • Нет связанных вопросов^_^