2016-05-01 7 views
9

मैं एक सेवा है जो निम्न स्वरूप में JSON आउटपुट पर ठोकर खाई के साथ Json.NET कस्टम JsonConverter:डेटा प्रकार

{ 
    "Author": "me", 
    "Version": "1.0.0", 
    "data.Type1": { 
     "Children": [ 
      { 
       "data.Type1": { 
        "Children": [ 
         { 
          "data.Type2": { 
           "name": "John", 
           "surname": "Doe" 
          } 
         } 
        ] 
       } 
      }, 
      { 
       "data.Type3": { 
        "dob": "1990-01-01" 
       } 
      } 
     ] 
    } 
} 

डेटा प्रकार के नाम संपत्ति के नाम के रूप में संरक्षित कर रहे हैं और उनके मान वास्तविक वस्तुओं रहे हैं। वे सभी data. उपसर्ग के साथ शुरू करते हैं।

{ // Root 
    "Author": "me", 
    "Version": "1.0.0", 
    "Children": [ // Type1 
     { 
      "Children": [ // Type1 
       { // Type2 
        "Name": "John", 
        "Surname": "Doe" 
       } 
      ] 
     }, 
     { // Type3 
      "DoB": "1990-01-01" 
     } 
    ] 
} 
निम्नलिखित वर्गों के साथ

:

मैं बाद में प्राप्त करना चाहते हैं क्या कुछ इस तरह है

class Type1 { 
    ICollection<object> Children { get; set; } 
} 

class Type2 { 
    public string Name { get; set; } 
    public string Surname { get; set; } 
} 

class Type3 { 
    public DateTime DoB { get; set; } 
} 

class Root 
{ 
    public string Author { get; set; } 
    public string Version { get; set; } 
    public Type1 Children { get; set; } 
} 

प्रश्न

मैं जोड़ा में इस deserialize कैसे सी # कक्षाएं, डेटा प्रकारों को ध्यान में रखते हुए और पेड़ से उन्हें हटा रही हैं?

मैंने कस्टम JsonConverter के साथ प्रयास किया है, लेकिन कनवर्टर को गतिशील रूप से चुनने के तरीके से संघर्ष कर रहा हूं, क्योंकि सबसे आसान तरीका संपत्ति पर एक विशेषता डालना होगा, लेकिन यह समर्थित नहीं है।

एक छोटा सा उदाहरण बहुत अच्छा होगा।

उत्तर

8

हालांकि इस JSON प्रारूप कुछ हद तक असामान्य है और गतिशील संपत्ति के नाम की वजह से विशेषताओं का उपयोग तैयार नहीं है, यह अभी भी संभव है एक छोटा सा परिवर्तन के साथ अपनी पसंद के वर्ग संरचना में यह deserialize करने के लिए एक JsonConverter बनाने के लिए: मैं आप Root कक्षा में Children संपत्ति को बदलने की सिफारिश करेंगेमें Children संपत्ति दर्पण एक ICollection<object> होने के लिए 210 वर्ग जैसा कि अब है, यह आपके वांछित आउटपुट की संरचना से मेल नहीं खाता है (जहां Children एक सरणी के रूप में दिखाया गया है, ऑब्जेक्ट नहीं) और अन्यथा कनवर्टर में अतिरिक्त कोड की आवश्यकता होगी ताकि सही तरीके से संभाल सकें।

Root root = JsonConvert.DeserializeObject<Root>(json, new CustomConverter()); 
: इस कनवर्टर आप इस तरह अपनी कक्षाओं को deserialize कर सकते हैं साथ

class CustomConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return (objectType == typeof(Root)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JObject obj = JObject.Load(reader); 
     Root root = new Root(); 
     root.Author = (string)obj["Author"]; 
     root.Version = (string)obj["Version"]; 
     root.Children = ((Type1)DeserializeTypeX(obj, serializer)).Children; 
     return root; 
    } 

    private object DeserializeTypeX(JObject obj, JsonSerializer serializer) 
    { 
     JProperty prop = obj.Properties().Where(p => p.Name.StartsWith("data.")).First(); 
     JObject child = (JObject)prop.Value; 
     if (prop.Name == "data.Type1") 
     { 
      List<object> children = new List<object>(); 
      foreach (JObject jo in child["Children"].Children<JObject>()) 
      { 
       children.Add(DeserializeTypeX(jo, serializer)); 
      } 
      return new Type1 { Children = children }; 
     } 
     else if (prop.Name == "data.Type2") 
     { 
      return child.ToObject<Type2>(serializer); 
     } 
     else if (prop.Name == "data.Type3") 
     { 
      return child.ToObject<Type3>(serializer); 
     } 
     throw new JsonSerializationException("Unrecognized type: " + prop.Name); 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

सशस्त्र:

class Root 
{ 
    public string Author { get; set; } 
    public string Version { get; set; } 
    public ICollection<object> Children { get; set; } 
} 

यहाँ है कि मैं क्या कनवर्टर के लिए के साथ आया था (यह मानते हुए उपरोक्त परिवर्तन किया जाता है) है

फिर आप इस तरह के नए प्रारूप में क्रमबद्ध कर सकते हैं:

JsonSerializerSettings settings = new JsonSerializerSettings 
{ 
    DateFormatString = "yyyy-MM-dd", 
    Formatting = Formatting.Indented 
}; 

Console.WriteLine(JsonConvert.SerializeObject(root, settings)); 

पहेली: https://dotnetfiddle.net/ESNMLE

0

यह सुनिश्चित नहीं है कि यह काम करेगा, लेकिन क्या आपने ऑब्जेक्ट को क्रमबद्ध करने के लिए न्यूटॉन्सॉफ्ट.जेसन का उपयोग करने की कोशिश की है और कक्षा गुणों पर जेसनप्रोपर्टी टैग शामिल हैं? मुझे पता है कि यह एक कक्षा में जेसन को deserializing जब काम करेगा।

<JsonProperty("user_id")> 
Public Property UserID As String 
//Converts Json {user_id: 123} to class.UserID = 123 

Newtonsoft साथ क्रमानुसार करने, पहली परियोजना में Newtonsoft शामिल तो

Dim stringJson As String = Newtonsoft.Json.JsonConvert.SerializeObject(root) 
+0

आपके उत्तर के लिए धन्यवाद।मैंने कोशिश की, लेकिन समस्या यह है कि पूरे स्तर को हटा दिया जाना चाहिए और प्रतिस्थापित किया जाना चाहिए, क्योंकि वे केवल उस प्रकार के रूप में कार्य करते हैं जो कि वे किस प्रकार का प्रतिनिधित्व करते हैं, जहां जेसनप्रोपर्टी केवल क्लास नाम और जेसन संपत्ति के नाम के बीच मैप करना है। –

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