web-dev-qa-db-ja.com

ネストされたJSONをC#オブジェクトにデシリアライズします

次のような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"]
}

このJSONをc#オブジェクトで表すためにいくつかのアプローチを試みました(ここにリストするには多すぎます)。リストと辞書を試してみましたが、これを表現しようとした最近の例を次に示します。

    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を除いて実際にデシリアライズされることはありません。

シンプルなはずですが、何らかの理由で正しいオブジェクト表現がわかりません

13
user3574076

ために "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; }
}

これは、アイテム名が"Item322A"および"Item2B"は応答ごとに異なり、これらの名前を辞書キーとして読み取ります。

サンプル フィドル

13
dbc

表現のためにこのサイトを使用してください:

http://json2csharp.com/

このような何かがあなたを助けるかもしれません

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);
17
R.You

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