JSON.net के साथ JSON ऑब्जेक्ट एरे का वर्णन करना


118

मैं एक एपीआई का उपयोग करने का प्रयास कर रहा हूं जो उनके लौटे हुए जोंस के लिए अनुसरण उदाहरण संरचना का उपयोग करता है

[
   {
      "customer":{
         "first_name":"Test",
         "last_name":"Account",
         "email":"test1@example.com",
         "organization":"",
         "reference":null,
         "id":3545134,
         "created_at":"2013-08-06T15:51:15-04:00",
         "updated_at":"2013-08-06T15:51:15-04:00",
         "address":"",
         "address_2":"",
         "city":"",
         "state":"",
         "zip":"",
         "country":"",
         "phone":""
      }
   },
   {
      "customer":{
         "first_name":"Test",
         "last_name":"Account2",
         "email":"test2@example.com",
         "organization":"",
         "reference":null,
         "id":3570462,
         "created_at":"2013-08-12T11:54:58-04:00",
         "updated_at":"2013-08-12T11:54:58-04:00",
         "address":"",
         "address_2":"",
         "city":"",
         "state":"",
         "zip":"",
         "country":"",
         "phone":""
      }
   }
]

JSON.net निम्नलिखित संरचना की तरह कुछ के साथ बहुत अच्छा काम करेगा

{
    "customer": {
        ["field1" : "value", etc...],
        ["field1" : "value", etc...],
    }
}

लेकिन मैं यह नहीं बता सकता कि प्रदान की गई संरचना से खुश होने के लिए इसे कैसे प्राप्त किया जाए।

डिफ़ॉल्ट JsonConvert.DeserializeObject (सामग्री) का उपयोग करने से ग्राहक की सही संख्या का परिणाम मिलता है लेकिन सभी डेटा शून्य है।

एक ग्राहक-सूची (नीचे) कुछ करने से "वर्तमान JSON सरणी" को अपवाद नहीं बनाया जा सकता है

public class CustomerList
{
    public List<Customer> customer { get; set; }
}

विचार?


क्या इससे आपके सवाल का जवाब मिलता है? C # के साथ JSON का
वर्णन करें

जवाबों:


187

आप अपने जोंस का वर्णन करने के लिए एक नया मॉडल बना सकते हैं CustomerJson:

public class CustomerJson
{
    [JsonProperty("customer")]
    public Customer Customer { get; set; }
}

public class Customer
{
    [JsonProperty("first_name")]
    public string Firstname { get; set; }

    [JsonProperty("last_name")]
    public string Lastname { get; set; }

    ...
}

और आप आसानी से अपने जौहर को दूर कर सकते हैं:

JsonConvert.DeserializeObject<List<CustomerJson>>(json);

आशा करता हूँ की ये काम करेगा !

प्रलेखन: सीरियल और वर्णन करना JSON


1
धन्यवाद। इस मुद्दे पर सोच रही थी। जैसा कि आपने उत्तर दिया पहले आपका उत्तर स्वीकार किया गया था।
शॉन सी।

2
JsonConvert.DeserializeObject <सूची <CustomerJson >> (JSON); स्ट्रिंग इनपुट के लिए एकदम सही काम करता है।
मार्केल मेल्स

DeserializeObject()एआरएम चलाने वाले एंड्रॉइड फोन पर धीमा है। उस मामले के लिए कोई बेहतर समाधान?
तद्ज

1
एक जॉबजेक्ट के साथ नेविगेट करने की कोशिश करेंJObject.Parse(json);
जोफ्री केर्न

47

जो लोग कोई मॉडल नहीं बनाना चाहते हैं, वे निम्नलिखित कोड का उपयोग करें:

var result = JsonConvert.DeserializeObject<
  List<Dictionary<string, 
    Dictionary<string, string>>>>(content);

नोट: यह आपके JSON स्ट्रिंग के लिए काम नहीं करता है । यह किसी भी JSON संरचना के लिए एक सामान्य समाधान नहीं है।


10
यह एक भयानक समाधान है। इसके बजाय, यदि आप मॉडल नहीं बनाना चाहते हैं, तो उपयोग करेंvar result = JsonConvert.DeserializeObject<Tuple<string, string, string>>(content);
a11smiles

1
@ a11smiles कृपया समझाएं कि यह एक भयानक समाधान क्यों है।
टायलर लॉन्ग

2
सबसे पहले, विभिन्न प्रकार के IEnumerableकार्यान्वयन के लिए अनावश्यक मेमोरी आवंटन (सूची की तुलना में <टुपल>)। दूसरा, आपका समाधान प्रत्येक शब्दकोश के लिए दो अलग-अलग कुंजी - 1 का अर्थ है। यदि कई ग्राहकों का पहला नाम समान है, तो क्या होगा? चाबियों पर कोई भेदभाव नहीं होगा। आपका समाधान इस संघर्ष को ध्यान में नहीं रखता है।
a11smiles

2
@ a11smiles प्रत्येक ग्राहक एक अलग शब्दकोश है। इसलिए कोई समस्या नहीं होगी यहां तक ​​कि एक ही नाम वाले कई ग्राहक हैं।
टायलर लॉन्ग

1
@ a11smiles मैं सोच रहा हूं कि आपको क्यों लगा var result = JsonConvert.DeserializeObject<Tuple<string, string, string>>(content);कि काम करेगा। जाहिरा तौर पर यह काम नहीं करता है
टायलर लॉन्ग

1

स्वीकृत उत्तर का उपयोग करके आपको प्रत्येक रिकॉर्ड का उपयोग करके उपयोग करना होगा Customers[i].customer, और आपको एक अतिरिक्त CustomerJsonवर्ग की आवश्यकता है , जो थोड़ा कष्टप्रद है। यदि आप ऐसा नहीं करना चाहते हैं, तो आप निम्नलिखित का उपयोग कर सकते हैं:

public class CustomerList
{
    [JsonConverter(typeof(MyListConverter))]
    public List<Customer> customer { get; set; }
}

ध्यान दें कि मैं एक का उपयोग कर रहा हूँ List<>, एक ऐरे का नहीं। अब निम्न वर्ग बनाएं:

class MyListConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        var list = Activator.CreateInstance(objectType) as System.Collections.IList;
        var itemType = objectType.GenericTypeArguments[0];
        foreach (var child in token.Values())
        {
            var childToken = child.Children().First();
            var newObject = Activator.CreateInstance(itemType);
            serializer.Populate(childToken.CreateReader(), newObject);
            list.Add(newObject);
        }
        return list;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
    }
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}

1

ऊपर जो बताया गया था, उसमें थोड़ा संशोधन करें। मेरा Json प्रारूप, जो मान्य था

{
    mycollection:{[
           {   
               property0:value,
               property1:value,
             },
             {   
               property0:value,
               property1:value,
             }
           ]

         }
       }

एलेक्सडेव की प्रतिक्रिया का उपयोग करते हुए, मैंने प्रत्येक बच्चे को यह लूपिंग किया, जिससे पाठक बना

 public partial class myModel
{
    public static List<myModel> FromJson(string json) => JsonConvert.DeserializeObject<myModelList>(json, Converter.Settings).model;
}

 public class myModelList {
    [JsonConverter(typeof(myModelConverter))]
    public List<myModel> model { get; set; }

}

class myModelConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        var list = Activator.CreateInstance(objectType) as System.Collections.IList;
        var itemType = objectType.GenericTypeArguments[0];
        foreach (var child in token.Children())  //mod here
        {
            var newObject = Activator.CreateInstance(itemType);
            serializer.Populate(child.CreateReader(), newObject); //mod here
            list.Add(newObject);
        }
        return list;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
    }
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();

}

0

JC_VA से आगे संशोधन, उसके पास क्या है, और MyModelConverter को प्रतिस्थापित करें ...

public class MyModelConverter : JsonConverter
{
    //objectType is the type as specified for List<myModel> (i.e. myModel)
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader); //json from myModelList > model
        var list = Activator.CreateInstance(objectType) as System.Collections.IList; // new list to return
        var itemType = objectType.GenericTypeArguments[0]; // type of the list (myModel)
        if (token.Type.ToString() == "Object") //Object
        {
            var child = token.Children();
            var newObject = Activator.CreateInstance(itemType);
            serializer.Populate(token.CreateReader(), newObject);
            list.Add(newObject);
        }
        else //Array
        {
            foreach (var child in token.Children())
            {
                var newObject = Activator.CreateInstance(itemType);
                serializer.Populate(child.CreateReader(), newObject);
                list.Add(newObject);
            }
        }
        return list;

    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsGenericType && (objectType.GetGenericTypeDefinition() == typeof(List<>));
    }
    public override bool CanWrite => false;
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
}

यह या तो json के लिए काम करना चाहिए

myModelList{
 model: [{ ... object ... }]
}

या

myModelList{
 model: { ... object ... }
}

वे दोनों समाप्त हो जाएंगे जैसे कि वे थे

myModelList{
 model: [{ ... object ... }]
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.