2011-10-04 15 views
5

मैं DataContractJsonSerializer एक वस्तु hierarchie में एक json स्ट्रिंग पार्स करने के लिए उपयोग हो सकता है। json स्ट्रिंग इस तरह दिखता है:सी # 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

जेसन इस के साथ असंगत क्यों है? फिक्सिंग-ऑन-सोर्स संभव होगा? –

+0

यह कैसे विफल हो जाता है? क्या त्रुटि है? – bryanmac

उत्तर

3

आपको यह नियंत्रित करने JSON तो यकीन है कि जिम्मेदार बताते हैं कि कर रहा है एक सरणी बनाई गई है, भले ही वह केवल एक ही तत्व शामिल हैं। फिर दूसरा तत्व इस तरह दिखेगा और ठीक से पार्स करेगा।

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

जैसा कि डैनियल ने कहा, यदि आप जेसन के निर्माण को नियंत्रित कर सकते हैं, तो इस तरह जारी रखना बेहतर है। लेकिन जैसे this लिंक से JSONObject वर्ग कुछ कोड लिखने के लिए यदि आप नहीं है, तो आप Json.Net पुस्तकालय & उपयोग कर सकते हैं कर सकते हैं:

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 के साथ काम करने की कोशिश नेट और कोई भी सभी मामलों में सफलतापूर्वक किसी ऑब्जेक्ट को deserialize नहीं होगा। मैंने 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.Net यह एक आइटम के साथ नहीं बल्कि एक अपवाद फेंकने की तुलना में एक संग्रह करने के लिए अक्रमांकन मजबूर करने के लिए अनुमति देने के लिए के लिए एक सेटिंग जोड़ देगा। यह एक शर्म की बात है कि आपको मैन्युअल रूप से सभी पार्सिंग करना होगा जब JSON का केवल एक छोटा सा हिस्सा सही ढंग से पार्स नहीं करता है।