2011-10-04 17 views
5

DataContractJsonSerializerを使用して、json文字列をオブジェクト階層に解析します。 JSON文字列は次のようになります。あなたは、「属性」のサブ値を見ることができるように値が配列または単一項目の場合、C#DataContractJsonSerializerが失敗する

{ 
    "groups": [ 
     { 
      "attributes": [ 
       { 
        "sortOrder": "1", 
        "value": "A" 
       }, 
       { 
        "sortOrder": "2", 
        "value": "B" 
       } 
      ] 
     }, 
     { 
      "attributes": { 
       "sortOrder": "1", 
       "value": "C" 
      } 
     } 
    ] 
} 

が配列または単一の項目することができます。

[DataContract] 
public class ItemGroup 
{ 
    [DataMember(Name="attributes")] 
    public List<DetailItem> Items { get; set; } 
} 

これは最初のもののために動作しますが、二番目に失敗します。 は、私はこの問題はoccuresコード部分を発見しました。

この回答は誰にもありますか?

Thxを

+0

なぜこれとjsonは矛盾しますか?ソースの固定は可能でしょうか? –

+0

どうして失敗するのですか?何のエラー? – bryanmac

答えて

3

あなたはJSONは、その後、属性はそれだけで一つの要素が含まれている場合でも、配列であることを確認して作成される方法を制御します。次に、2番目の要素はこのようになり、細かい解析を行います。

{ 
     "attributes": [{ 
      "sortOrder": "1", 
      "value": "C" 
     }] 
    } 
3

Daniel氏によると、Jsonの作成を制御できる場合は、その方法を続行することをお勧めします。 しかし、あなたは、あなたがJson.Netライブラリ&を使用することができないことができるかどうかのように thisリンクからJsonObjectクラスは、いくつかのコードを書くために:

JObject o = (JObject)JsonConvert.DeserializeObject(input); 
dynamic json = new JsonObject(o); 
foreach (var x in json.groups) 
{ 
     var attrs = x.attributes; 
     if (attrs is JArray) 
     { 
      foreach (var y in attrs) 
      { 
       Console.WriteLine(y.value); 
      } 
     } 
     else 
     { 
      Console.WriteLine(attrs.value); 
     } 
} 
+0

これはいいアイデアです+1 –

1

が、私はこのDataContractJsonSerializer、JavaScriptSerializer、およびJSONでの作業を取得しようとしました.Netとnoneは、すべてのケースでオブジェクトに正常に逆シリアル化されます。ダイナミクスと余分なJsonObjectクラスを使用することなく、JSON.Netを使用してL.Bと同様のアプローチを使用しました。あなたのシナリオに私のコードを適応させることは、次のようになります:JSON.Netは、それが例外をスローするのではなく、単一の項目をコレクションに、デシリアライゼーションを強制できるようにするために

private List<ItemGroup> ParseItemGroupList(string input) 
    { 
     JObject json = JObject.Parse(input); 

     List<ItemGroup> groups = new List<ItemGroup>(); 
     JArray gArray = json["groups"] as JArray; 
     foreach (var gToken in gArray) 
     { 
      ItemGroup newGroup = new ItemGroup(); 
      JToken attrToken = gToken["attributes"] as JToken; 
      if (attrToken is JArray) 
      { 
       newGroup.Items = attrToken.Children().Select(MapDetailItem()).ToList(); 
      } 
      else 
      { 
       newGroup.Items = new List<DetailItem>() { MapDetailItem().Invoke(attrToken) }; 
      } 

      groups.Add(newGroup); 
     } 

     return groups; 
    } 

    private static Func<JToken, DetailItem> MapDetailItem() 
    { 
     return json => new DetailItem 
     { 
      SortOrder = (string)json["sortOrder"], 
      Value = (string)json["value"] 
     }; 
    } 

がうまくいけば、誰かが設定を追加します。自動的に正しく解析されないJSONの小さな部分が1つしかない場合は、すべての解析を手動で行う必要があります。

関連する問題