2011-03-07 22 views
34

ऑब्जेक्ट JSON deserializing JSON.NET पुस्तकालयों का उपयोग कर फेसबुक से लौटाए गए डेटा को बेकार करने में मुझे कुछ परेशानी हो रही है।कभी-कभी सरणी और कभी-कभी

JSON सिर्फ एक सरल दीवार पद से लौटे लगता है:

{ 
    "attachment":{"description":""}, 
    "permalink":"http://www.facebook.com/permalink.php?story_fbid=123456789" 
} 

JSON लौटे तरह के लिए एक तस्वीर दिखाई देती है:

"attachment":{ 
     "media":[ 
      { 
       "href":"http://www.facebook.com/photo.php?fbid=12345", 
       "alt":"", 
       "type":"photo", 
       "src":"http://photos-b.ak.fbcdn.net/hphotos-ak-ash1/12345_s.jpg", 
       "photo":{"aid":"1234","pid":"1234","fbid":"1234","owner":"1234","index":"12","width":"720","height":"482"}} 
     ], 

सब कुछ काम करता है महान है और मैं कोई समस्या नहीं। मैं अब निम्नलिखित JSON के साथ एक मोबाइल ग्राहक से एक साधारण दीवार पोस्ट दिखाई देती है, और अक्रमांकन अब यह एक ही पोस्ट के साथ विफल रहता है:

public class FacebookAttachment 
    { 
     public string Name { get; set; } 
     public string Description { get; set; } 
     public string Href { get; set; } 
     public FacebookPostType Fb_Object_Type { get; set; } 
     public string Fb_Object_Id { get; set; } 

     [JsonConverter(typeof(FacebookMediaJsonConverter))] 
     public List<FacebookMedia> { get; set; } 

     public string Permalink { get; set; } 
    } 
:

"attachment": 
    { 
     "media":{}, 
     "name":"", 
     "caption":"", 
     "description":"", 
     "properties":{}, 
     "icon":"http://www.facebook.com/images/icons/mobile_app.gif", 
     "fb_object_type":"" 
    }, 
"permalink":"http://www.facebook.com/1234" 

यहाँ वर्ग मैं के रूप में deserializing रहा है

फेसबुक मीडिया मीडियासन कनवर्टर का उपयोग किए बिना, मुझे एक त्रुटि मिलती है: जेएसओएन ऑब्जेक्ट को 'System.Collections.Generic.List`1 [Facebook मीडिया]' टाइप में deserialize नहीं कर सकता। जो समझ में आता है, क्योंकि JSON में, मीडिया संग्रह नहीं है।

मैं इस पोस्ट जो एक समान समस्या का वर्णन करता पाया, इसलिए मैं इस मार्ग नीचे जाना करने का प्रयास किया: अब

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
{ 
    if (reader.TokenType == JsonToken.StartArray) 
      return serializer.Deserialize<List<FacebookMedia>>(reader); 
    else 
      return null; 
} 

कौन सा ठीक काम करता है, मैं छोड़कर मिलती है: Deserialize JSON, sometimes value is an array, sometimes "" (blank string)

मेरे कनवर्टर की तरह दिखता है कोई नया अपवाद:

अंदर JsonSerializerInternalReader.cs, CreateValueInternal(): अनपेक्षित टोकन जबकि deserializing वस्तु: PropertyName

पाठक का मूल्य। वैल्यू "परमालिंक" है। मैं स्पष्ट रूप से स्विच में देख सकता हूं कि JsonToken.PropertyName के लिए कोई मामला नहीं है।

क्या मेरे कनवर्टर में अलग-अलग करने की ज़रूरत है? किसी भी मदद के लिए धन्यवाद।

उत्तर

20

JSON.NET के डेवलपर प्रोजेक्ट codeplex साइट पर मदद करने के समाप्त हो गया यहाँ समाधान है:।।

समस्या किया गया था, जब वह एक JSON ऑब्जेक्ट था, मैं विशेषता अतीत पढ़ नहीं किया गया था। यहां सही कोड है:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
{ 
    if (reader.TokenType == JsonToken.StartArray) 
    { 
     return serializer.Deserialize<List<FacebookMedia>>(reader); 
    } 
    else 
    { 
     FacebookMedia media = serializer.Deserialize<FacebookMedia>(reader); 
     return new List<FacebookMedia>(new[] {media}); 
    } 
} 

जेम्स उपरोक्त विधि के लिए यूनिट परीक्षण प्रदान करने के लिए भी बहुत दयालु थे।

2

सिस्टम पर एक नज़र डालें। सी # फ्रेमवर्क में रनटाइम। सिराइलाइजेशन नेमस्पेस, यह आपको उस स्थान पर ले जायेगा जहां आप बहुत जल्दी बनना चाहते हैं।

आप चाहते हैं, तो आप बाहर कुछ उदाहरण कोड this परियोजना (मेरे अपने काम प्लग करने के लिए कोशिश नहीं कर में जाँच कर सकते हैं, लेकिन मैं सिर्फ सुंदर है कि वास्तव में क्या कर रहे हैं बहुत लेकिन एक अलग स्रोत API के साथ समाप्त हो गया।

यह आशा मदद करता है

+1

-1 कोड नमूने के लिंक के साथ किसी तृतीय पक्ष लाइब्रेरी पर ढांचे के आंतरिक सिद्ध हिस्से के उपयोग की सिफारिश करने के लिए? – jonezy

+0

जो बहुत असामान्य लगता है। – jonezy

+0

मुझे यकीन नहीं है कि -1 कहां से आया था। मैं प्रतिक्रिया की सराहना करता हूं। मुझे संदेह है कि यह शायद मामूली समस्या के लिए काफी हेवीवेट समाधान है (संभवतः JSON.NET के अपने दुरुपयोग के कारण)। ऐसा कहा जा रहा है, मैं सिस्टेम देने जा रहा हूं। रनटाइम। सरलीकरण विधियों को आज़माएं और देखें कि क्या यह बेहतर काम कर रहा है या नहीं। लिंक के लिए धन्यवाद। – mfanto

-2

मुझे लगता है कि आपको अपनी कक्षा इस तरह लिखनी चाहिए ... !!!

public class FacebookAttachment 
    { 

     [JsonProperty("attachment")] 
     public Attachment Attachment { get; set; } 

     [JsonProperty("permalink")] 
     public string Permalink { get; set; } 
    } 

public class Attachment 
    { 

     [JsonProperty("media")] 
     public Media Media { get; set; } 

     [JsonProperty("name")] 
     public string Name { get; set; } 

     [JsonProperty("caption")] 
     public string Caption { get; set; } 

     [JsonProperty("description")] 
     public string Description { get; set; } 

     [JsonProperty("properties")] 
     public Properties Properties { get; set; } 

     [JsonProperty("icon")] 
     public string Icon { get; set; } 

     [JsonProperty("fb_object_type")] 
     public string FbObjectType { get; set; } 
    } 
public class Media 
    { 
    } 
public class Properties 
    { 
    } 
19

इस मामले को संभालने के तरीके पर एक बहुत विस्तृत स्पष्टीकरण "Using a Custom JsonConverter to fix bad JSON results" पर उपलब्ध है।

संक्षेप में, आप डिफ़ॉल्ट JSON.NET कर

  1. एन्नोटेट संपत्ति मुद्दा

    [JsonConverter(typeof(SingleValueArrayConverter<OrderItem>))] 
    public List<OrderItem> items; 
    
  2. साथ कनवर्टर विस्तार कर सकते हैं यहां तक ​​कि अपने इच्छित प्रकार की एक सूची वापस करने के लिए कनवर्टर का विस्तार एक ऑब्जेक्ट के लिए

    public class SingleValueArrayConverter<T> : JsonConverter 
    { 
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
        { 
         throw new NotImplementedException(); 
        } 
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
        { 
         object retVal = new Object(); 
         if (reader.TokenType == JsonToken.StartObject) 
         { 
          T instance = (T)serializer.Deserialize(reader, typeof(T)); 
          retVal = new List<T>() { instance }; 
         } else if (reader.TokenType == JsonToken.StartArray) { 
          retVal = serializer.Deserialize(reader, objectType); 
         } 
         return retVal; 
        } 
    
        public override bool CanConvert(Type objectType) 
        { 
         return true; 
        } 
    } 
    

जैसा कि लेख में बताया गया है कि यह एक्सटेंशन पूरी तरह से सामान्य नहीं है लेकिन यह काम करता है यदि आप सूची प्राप्त करने के ठीक हैं।

+0

बिल्कुल सही। धन्यवाद। – NotMe

+0

मैं उलझन में हूं - मेरा लिखित जेसन फेंक रहा है? क्या मुझे इसे संभालने की ज़रूरत है? – nologo

संबंधित मुद्दे