2012-07-19 9 views
14

पर deserialize मैं न्यूटॉन्सॉफ्ट JSON.NET का उपयोग करने के लिए कुछ पुराने काम को बदलने की कोशिश कर रहा हूं। System.Web.Script.Serialization.JavaScriptSerializer.Deserialize विधि (उदा। यदि कोई लक्ष्य प्रकार निर्दिष्ट नहीं है) का उपयोग कर डिफ़ॉल्ट हैंडलिंग आंतरिक वस्तुओं के लिए Dictionary<string,object> वापस करना है।जेएसओएन को क्रमशः IDictionary <string, object>

यह वास्तव में जेएसओएन के लिए वास्तव में एक उपयोगी मूल प्रकार है क्योंकि यह ExpandoObjects द्वारा उपयोग किया जाने वाला अंतर्निहित प्रकार भी होता है और गतिशील प्रकारों के लिए सबसे समझदार आंतरिक कार्यान्वयन होता है।

अगर मैं इस प्रकार, उदा .:

var dict = JsonConvert.DeserializeObject<Dictionary<string,object>>(json); 

JSON.NET सही ढंग से सबसे बाहरी वस्तु संरचना deserialize होगा निर्दिष्ट करते हैं, लेकिन यह किसी भी आंतरिक संरचनाओं के लिए एक JObject प्रकार देता है। मुझे वास्तव में जो भी चाहिए वह बाहरी बाहरी संरचना के लिए किसी भी आंतरिक ऑब्जेक्ट-प्रकार संरचनाओं के लिए उपयोग किया जाना है।

क्या आंतरिक वस्तुओं के लिए उपयोग किए जाने वाले प्रकार को निर्दिष्ट करने का कोई तरीका है, न केवल बाहरी प्रकार लौटाया गया है?

उत्तर

7

जब जेसन का उपयोग करके अपनी जटिल वस्तुओं को Deserializing, आपको पैरामीटर के रूप में एक JsonSerializer सेटिंग्स जोड़ने की आवश्यकता है। यह सुनिश्चित करेगा कि सभी आंतरिक प्रकार ठीक से deserialized हो। फिर जब आप deserializing कर रहे हैं, उपयोग

string json= JsonConvert.SerializeObject(myObject, _jsonSettings) 

:

private JsonSerializerSettings _jsonSettings = new JsonSerializerSettings 
    { 
     TypeNameHandling = TypeNameHandling.All, 
     TypeNameAssemblyFormat = FormatterAssemblyStyle.Full 
    }; 

जब आपके वस्तु Serializing, आप SerializerSettings उपयोग कर सकते हैं

var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, _jsonSettings); 

इसके अलावा, जब आप को क्रमानुसार, को JsonSerializerSettings जोड़ने आपका SerializeObject (ऑब्जेक्ट, सेटिंग्स)

संपादित करें: आप टी भी बदल सकते हैं यदि आपको आवश्यकता है तो वह TypeNameHandling और TypeNameAssemblyFormat। मैंने उन्हें यह सुनिश्चित करने के लिए क्रमशः 'ऑल' और 'फुल' पर सेट किया है कि मेरी जटिल वस्तुओं को बिना किसी संदेह के क्रमबद्ध रूप से क्रमबद्ध और deserialized मिलता है, लेकिन इंटेलिजेंस आपको अन्य विकल्पों के साथ प्रदान करता है

+0

क्या यह सही उत्तर है? –

+1

@LukePuplett मुझे नहीं लगता कि यह सही है, पूछे गए सवाल के आधार पर। –

+0

प्रश्न के आधार पर यह सही जवाब नहीं है। –

15

जेसन.Net को जेसन स्ट्रिंग को deserialize करने के लिए IDictionary<string, object> में घर्षणित वस्तुओं और सरणी को deserializing सहित आपको एक कस्टम क्लास बनाने की आवश्यकता होगी जो JsonConverter Json.Net द्वारा प्रदान की गई सारणी कक्षा से प्राप्त हो।

यह आपके व्युत्पन्न JsonConverter में है जहां आप कार्यान्वित करते हैं कि जेसन से और ऑब्जेक्ट को कैसे लिखा जाना चाहिए।

आप इस तरह अपने कस्टम JsonConverter उपयोग कर सकते हैं:

public class DictionaryConverter : JsonConverter { 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { this.WriteValue(writer, value); } 

    private void WriteValue(JsonWriter writer, object value) { 
     var t = JToken.FromObject(value); 
     switch (t.Type) { 
      case JTokenType.Object: 
       this.WriteObject(writer, value); 
       break; 
      case JTokenType.Array: 
       this.WriteArray(writer, value); 
       break; 
      default: 
       writer.WriteValue(value); 
       break; 
     } 
    } 

    private void WriteObject(JsonWriter writer, object value) { 
     writer.WriteStartObject(); 
     var obj = value as IDictionary<string, object>; 
     foreach (var kvp in obj) { 
      writer.WritePropertyName(kvp.Key); 
      this.WriteValue(writer, kvp.Value); 
     } 
     writer.WriteEndObject(); 
    } 

    private void WriteArray(JsonWriter writer, object value) { 
     writer.WriteStartArray(); 
     var array = value as IEnumerable<object>; 
     foreach (var o in array) { 
      this.WriteValue(writer, o); 
     } 
     writer.WriteEndArray(); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
     return ReadValue(reader); 
    } 

    private object ReadValue(JsonReader reader) { 
     while (reader.TokenType == JsonToken.Comment) { 
      if (!reader.Read()) throw new JsonSerializationException("Unexpected Token when converting IDictionary<string, object>"); 
     } 

     switch (reader.TokenType) { 
      case JsonToken.StartObject: 
       return ReadObject(reader); 
      case JsonToken.StartArray: 
       return this.ReadArray(reader); 
      case JsonToken.Integer: 
      case JsonToken.Float: 
      case JsonToken.String: 
      case JsonToken.Boolean: 
      case JsonToken.Undefined: 
      case JsonToken.Null: 
      case JsonToken.Date: 
      case JsonToken.Bytes: 
       return reader.Value; 
      default: 
       throw new JsonSerializationException 
        (string.Format("Unexpected token when converting IDictionary<string, object>: {0}", reader.TokenType)); 
     } 
    } 

    private object ReadArray(JsonReader reader) { 
     IList<object> list = new List<object>(); 

     while (reader.Read()) { 
      switch (reader.TokenType) { 
       case JsonToken.Comment: 
        break; 
       default: 
        var v = ReadValue(reader); 

        list.Add(v); 
        break; 
       case JsonToken.EndArray: 
        return list; 
      } 
     } 

     throw new JsonSerializationException("Unexpected end when reading IDictionary<string, object>"); 
    } 

    private object ReadObject(JsonReader reader) { 
     var obj = new Dictionary<string, object>(); 

     while (reader.Read()) { 
      switch (reader.TokenType) { 
       case JsonToken.PropertyName: 
        var propertyName = reader.Value.ToString(); 

        if (!reader.Read()) { 
         throw new JsonSerializationException("Unexpected end when reading IDictionary<string, object>"); 
        } 

        var v = ReadValue(reader); 

        obj[propertyName] = v; 
        break; 
       case JsonToken.Comment: 
        break; 
       case JsonToken.EndObject: 
        return obj; 
      } 
     } 

     throw new JsonSerializationException("Unexpected end when reading IDictionary<string, object>"); 
    } 

    public override bool CanConvert(Type objectType) { return typeof(IDictionary<string, object>).IsAssignableFrom(objectType); } 
} 
:

var o = JsonConvert.DeserializeObject<IDictionary<string, object>>(json, new DictionaryConverter()); 

यहाँ एक कस्टम JsonConverter मैं अतीत में सफलता के साथ इस्तेमाल किया है के रूप में आप अपने प्रश्न में रूपरेखा ही लक्ष्यों को प्राप्त करने के लिए है

+0

यह समाधान बहुत अच्छा काम करता है। धन्यवाद! – smdrager

+0

[यहां अन्य पोस्ट पर यह समाधान है] (http://stackoverflow.com/a/38029052/1062224) –

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