2016-04-07 13 views
0

3番目のループに到達すると、テーブル上に「行」が見つからないために爆発します。どうして?Newtonsoft.JSONで動的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

http://jsonlint.com/ – tofutim

+0

であなたのJSONをチェックしますコードの再フォーマット – Thomas

答えて

1

Tableプロパティは、1つのインスタンスで、別の内のオブジェクトとして配列としてフォーマットされていました。前者は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は、テーブルを含む2つのオブジェクトの間で異なります。

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

そして、あなたの第2のクライアントオブジェクトが配列の配列を持っています

第一の目的は、行の配列を持つテーブルです。さらに、テーブル配列の外にあるそのクライアントオブジェクトに2番目の行の配列があります。

 "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をフォーマットするか、2つのタイプのテーブルは、あなたがそのJSONを持っているもののループに異なる方法を作成するのいずれかをお勧めしたいです。 1つはオブジェクトであり、もう1つは配列です。

たとえば、私はあなたのダイナミックをNewtonsoft.Json.LinqにあるNewtonsoft Jobjectに変更しました。これは、両方のテーブルでピックアップされます。一方はオブジェクトで、もう一方は配列です。あなたのJSONで

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

      }    
     }