2011-10-04 37 views
5

我使用DataContractJsonSerializer将json字符串解析为对象hierarchie。 JSON字符串看起来是这样的:当值可以是数组或单个项目时,C#DataContractJsonSerializer失败

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

正如你所看到的“属性”替代值可以是一个数组或一个项目。 我发现那里的问题occures代码部分:

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

这适用于第一个,但未能在第二个。

有没有人为此回答?

THX

+0

为什么json与此不一致?将固定在源可能? –

+0

它如何失败?什么错误? – bryanmac

回答

3

如果控制JSON是如何创建然后确保属性是一个数组,即使它只包含一个元素。然后,第二个元素将看起来像这样并解析得很好。

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

正如丹尼尔所说,如果你可以控制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,并且在任何情况下都不会直接反序列化成一个对象。我使用了与L.B类似的方法,使用JSON.Net,尽管没有使用动态和额外的JsonObject类。适应我的代码添加到您的场景看起来像以下:

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.Net允许它迫使反序列化到一个集合与单个项目,而不是抛出异常。当只有一小部分JSON不能自动正确解析时,您必须手动执行所有解析操作,这真令人遗憾。

相关问题