Jobject.Parse बनाम JsonConvert.DeserializeObject


85

JsonConvert.DeserializeObject और JObject.Parse के बीच अंतर क्या है? जहाँ तक मैं बता सकता हूँ, दोनों एक स्ट्रिंग लेते हैं और Json.NET लाइब्रेरी में हैं। किस तरह की स्थिति एक को दूसरे की तुलना में सुविधाजनक बनाती है, या यह मुख्य रूप से सिर्फ प्राथमिकता है?

संदर्भ के लिए, यहां एक उदाहरण है कि दोनों एक ही काम करते हैं - एक जोंस स्ट्रिंग को पार्स करें और एक जोंस विशेषताओं की सूची लौटाएं।

public ActionResult ReadJson()
{
    string countiesJson = "{'Everything':[{'county_name':null,'description':null,'feat_class':'Civil','feature_id':'36865',"
                    +"'fips_class':'H1','fips_county_cd':'1','full_county_name':null,'link_title':null,'url':'http://www.alachuacounty.us/','name':'Alachua County'"+ ",'primary_latitude':'29.7','primary_longitude':'-82.33','state_abbreviation':'FL','state_name':'Florida'},"+
                    "{'county_name':null,'description':null,"+ "'feat_class':'Civil','feature_id':'36866','fips_class':'H1','fips_county_cd':'3','full_county_name':null,'link_title':null,'url':'http://www.bakercountyfl.org/','name':'Baker County','primary_latitude':'30.33','primary_longitude':'-82.29','state_abbreviation':'FL','state_name':'Florida'}]}";

    //Can use either JSONParseObject or JSONParseDynamic here
    List<string> counties = JSONParseObject(countiesJson);
    JSONParseDynamic(countiesJson);
    return View(counties);
}

public List<string> JSONParseObject(string jsonText)
{
    JObject jResults = JObject.Parse(jsonText);
    List<string> counties = new List<string>();
    foreach (var county in jResults["Everything"])
    {
        counties.Add((string)county["name"]);
    }
    return counties;
}

public List<string> JSONParseDynamic(string jsonText)
{
    dynamic jResults = JsonConvert.DeserializeObject(jsonText);
    List<string> counties = new List<string>();
    foreach(var county in jResults.Everything)
    {
        counties.Add((string)county.name);
    }
    return counties;
}

जवाबों:


91

LINQ-to-JSON API ( JObject, JTokenआदि) समय से पहले इसकी संरचना को जानने की आवश्यकता के बिना JSON के साथ काम करने की अनुमति देने के लिए मौजूद है। आप किसी भी मनमाने JSON का उपयोग करने के लिए डिसेर्बलाइज कर सकते हैं JToken.Parse, फिर अन्य JTokenतरीकों का उपयोग करके इसकी सामग्री की जांच और हेरफेर कर सकते हैं । LINQ-to-JSON भी अच्छी तरह से काम करता है अगर आपको JSON से एक या दो मान (जैसे काउंटी का नाम) की आवश्यकता है।

JsonConvert.DeserializeObjectदूसरी ओर, मुख्य रूप से इसका उपयोग तब किया जाता है जब आप JSON की संरचना को समय से पहले जानते हैं और आप दृढ़ता से टाइप की गई कक्षाओं में भाग लेना चाहते हैं। उदाहरण के लिए, यहां बताया गया है कि आप अपने JSON से Countyवस्तुओं की सूची में काउंटी डेटा का पूरा सेट कैसे प्राप्त करेंगे ।

class Program
{
    static void Main(string[] args)
    {
        string countiesJson = "{'Everything':[{'county_name':null,'description':null,'feat_class':'Civil','feature_id':'36865',"
                +"'fips_class':'H1','fips_county_cd':'1','full_county_name':null,'link_title':null,'url':'http://www.alachuacounty.us/','name':'Alachua County'"+ ",'primary_latitude':'29.7','primary_longitude':'-82.33','state_abbreviation':'FL','state_name':'Florida'},"+
                "{'county_name':null,'description':null,"+ "'feat_class':'Civil','feature_id':'36866','fips_class':'H1','fips_county_cd':'3','full_county_name':null,'link_title':null,'url':'http://www.bakercountyfl.org/','name':'Baker County','primary_latitude':'30.33','primary_longitude':'-82.29','state_abbreviation':'FL','state_name':'Florida'}]}";

        foreach (County c in JsonParseCounties(countiesJson))
        {
            Console.WriteLine(string.Format("{0}, {1} ({2},{3})", c.name, 
               c.state_abbreviation, c.primary_latitude, c.primary_longitude));
        }
    }

    public static List<County> JsonParseCounties(string jsonText)
    {
        return JsonConvert.DeserializeObject<RootObject>(jsonText).Counties;
    }
}

public class RootObject
{
    [JsonProperty("Everything")]
    public List<County> Counties { get; set; }
}

public class County
{
    public string county_name { get; set; }
    public string description { get; set; }
    public string feat_class { get; set; }
    public string feature_id { get; set; }
    public string fips_class { get; set; }
    public string fips_county_cd { get; set; }
    public string full_county_name { get; set; }
    public string link_title { get; set; }
    public string url { get; set; }
    public string name { get; set; }
    public string primary_latitude { get; set; }
    public string primary_longitude { get; set; }
    public string state_abbreviation { get; set; }
    public string state_name { get; set; }
}

ध्यान दें कि Json.Net JsonConvert.DeserializeObjectविधि को किस प्रकार का ऑब्जेक्ट बनाने के लिए निर्धारित करने के लिए दिए गए प्रकार तर्क का उपयोग करता है ।

बेशक, यदि आप कॉल करते समय एक प्रकार निर्दिष्ट नहीं करते हैं DeserializeObject, या आप का उपयोग करते हैं objectया dynamic, तो Json.Net के पास कोई विकल्प नहीं है JObject। (आप अपने लिए देख सकते हैं कि आपका डायनामिक वैरिएबल वास्तव में JObjectचेक करके पकड़ता है jResults.GetType().FullName।) तो उस स्थिति में, JsonConvert.DeserializeObjectऔर दोनों के बीच बहुत अंतर नहीं है JToken.Parse; या तो आप एक ही परिणाम देगा।


अच्छी तरह से सोचा जवाब के लिए धन्यवाद! ऑब्जेक्ट बनाम डायनामिक डिस्क्रिप्टर अब समझ में आता है। आपके द्वारा दिया गया उदाहरण भी बहुत अच्छा है - जो कि JsonParseDynamic के साथ होने की तुलना में बहुत आसान लगता है।
हबेटिश


1
क्या DeserializeObject जौन में अतिरिक्त गुणों के प्रति सहिष्णु है, जो कक्षा में मौजूद नहीं है। क्या यह उन्हें अनदेखा करेगा या अपवाद फेंक देगा?
माइकल फ्रीजिम

1
@MichaelFreidgeim यह MissingMemberHandlingसेटिंग द्वारा नियंत्रित किया जाता है। डिफ़ॉल्ट अतिरिक्त गुणों को अनदेखा करना है।
ब्रायन रोजर्स

प्रदर्शन-वार, एक गतिशील वस्तु की तुलना में धीमी या तेज होती जा रही है, औसतन, इसे जोरदार-टाइप किए गए वर्ग के लिए deserializing से? मैं एक के बाद दूसरे से तेज़ होने के अलग-अलग कारण देख सकता हूं, लेकिन मुझे आश्चर्य है कि अगर डायनामिक का उपयोग तेजी से किया जा सकता है क्योंकि इसमें प्रतिबिंब का उपयोग करने की आवश्यकता नहीं है?
डायनेडो

27

JsonConvert.DeserializeObject का जोबजेक्ट पर एक फायदा है। मोटे: कस्टम JsonSerializerSettings का उपयोग करना संभव है।

यह बहुत उपयोगी हो सकता है जैसे कि यदि आप यह नियंत्रित करना चाहते हैं कि तिथियां कैसे डिसरलाइज़ की जाती हैं। डिफ़ॉल्ट रूप से दिनांक दिनांक ऑब्जेक्ट्स में deserialized हैं। इसका मतलब यह है कि आप एक दूसरे समय क्षेत्र के साथ डेट के साथ समाप्त हो सकते हैं जो कि जॉन स्ट्रिंग में है।

आप इस व्यवहार को JsonSerializerSetting बनाकर और DateParseHandling को DateParseHandling.DateTimeOffset पर सेट करके बदल सकते हैं।

एक उदाहरण:

var json = @"{ ""Time"": ""2015-10-28T14:05:22.0091621+00:00""}";
Console.WriteLine(json);
// Result: { "Time": "2015-10-28T14:05:22.0091621+00:00" }

var jObject1 = JObject.Parse(json);
Console.WriteLine(jObject1.ToString());
// Result: { "Time": "2015-10-28T15:05:22.0091621+01:00" }

var jObject2 = Newtonsoft.Json.JsonConvert.DeserializeObject(json, 
  new Newtonsoft.Json.JsonSerializerSettings 
  { 
    DateParseHandling = Newtonsoft.Json.DateParseHandling.DateTimeOffset 
  });
Console.WriteLine(jObject2.ToString());
// Result: { "Time": "2015-10-28T14:05:22.0091621+00:00" }

अगर आपको पता है कि जिस कक्षा में आप जा रहे हैं (यानी गतिशील नहीं है), क्या DeserializeObject का उपयोग करना तेजी से नहीं होना चाहिए?
डायनेडो

0

मुझे एक फायदा पता था कि JsonConvert.DeserializeObject एक Array / List json टेक्स्ट को सीधे डीरिशियल कर सकता है, लेकिन JObject नहीं कर सकता।

नमूना कोड नीचे आज़माएं:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

namespace NetCoreJsonNETDemo
{
    internal class Person
    {
        [JsonProperty]
        internal string Name
        {
            get;
            set;
        }

        [JsonProperty]
        internal int? Age
        {
            get;
            set;
        }
    }

    internal class PersonContainer
    {
        public List<Person> Persons
        {
            get;
            set;
        }
    }

    class Program
    {
        static T RecoverPersonsWithJsonConvert<T>(string json)
        {
            return JsonConvert.DeserializeObject<T>(json);
        }

        static T RecoverPersonsWithJObejct<T>(string json) where T : class
        {
            try
            {
                return JObject.Parse(json).ToObject<T>();
            }
            catch (Exception ex)
            {
                Console.WriteLine("JObject threw an Exception: " + ex.Message);
                return null;
            }
        }

        static void Main(string[] args)
        {
            List<Person> persons = new List<Person>();

            persons.Add(new Person()
            {
                Name = "Jack",
                Age = 18
            });

            persons.Add(new Person()
            {
                Name = "Sam",
                Age = null
            });

            persons.Add(new Person()
            {
                Name = "Bob",
                Age = 36
            });

            string json = JsonConvert.SerializeObject(persons, new JsonSerializerSettings()
            {
                Formatting = Formatting.Indented
            });

            List<Person> newPersons = RecoverPersonsWithJsonConvert<List<Person>>(json);
            newPersons = RecoverPersonsWithJObejct<List<Person>>(json);//JObject will throw an error, since the json text is an array.

            PersonContainer personContainer = new PersonContainer()
            {
                Persons = persons
            };

            json = JsonConvert.SerializeObject(personContainer, new JsonSerializerSettings()
            {
                Formatting = Formatting.Indented
            });

            newPersons = RecoverPersonsWithJObejct<PersonContainer>(json).Persons;

            newPersons = null;
            newPersons = RecoverPersonsWithJsonConvert<PersonContainer>(json).Persons;

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

1
JToken.Parse () कर सकते हैं :)
फ्रोड निल्सन

1
@FrodeNilsen इसके अलावा, JToken.Parse () मेरे परीक्षणों के अनुसार, इस पृष्ठ पर सभी गतिशील / deserialization विधियों में से सबसे तेज़ प्रतीत होता है।
मेसन जी। ज़्विती

0

उपयोग के आसपास यहां दिए गए उत्तरों के अलावा, जो मेरे अनुसार सही हैं: Jobject.Parse-> जब Json दृढ़ता से टाइप नहीं किया जाता है या आप समय से पहले Json की संरचना को नहीं जानते हैं

JsonConvert.DeserializeObject<T>-> जब आप जानते हैं कि किस वर्ग या प्रकार में जोंस को डालना है, तो Tयह एक जटिल वर्ग या सरल प्रकार हो सकता है

मेरा उत्तर उस स्थिति में प्रदर्शन पर आधारित है, जहां संरचना ज्ञात नहीं है, जैसा कि ओपी कोड में दिया गया है, अगर हम प्रदर्शन के लिए दोनों तरीकों के उपयोग को बेंचमार्क करते हैं, तो यह देखा गया है कि Jobject.Parse()आवंटित स्मृति के मामले में अच्छी तरह से किराए पर, कृपया नाम को अनदेखा करें तरीकों की, मैं पहले 'JsonConvert.DeserializeObject' के साथ विधि को बुला रहा हूं और फिर दूसरी विधि के साथ हैJobject.Parse

यहां छवि विवरण दर्ज करें

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