JSON.NET का उपयोग करके C # के लिए JSON डेटा का वर्णन करना


144

मैं C # और JSON डेटा के साथ काम करने के लिए अपेक्षाकृत नया हूं और मार्गदर्शन मांग रहा हूं। मैं .NET3.5SP1 और JSON.NET 3.5r6 के साथ C # 3.0 का उपयोग कर रहा हूं।

मेरे पास एक परिभाषित C # वर्ग है जिसे मुझे JSON संरचना से आबाद करने की आवश्यकता है। हालाँकि, वेब सेवा से पुनर्प्राप्त की गई प्रविष्टि के लिए हर JSON संरचना में वे सभी संभावित विशेषताएँ नहीं हैं जो C # वर्ग में परिभाषित हैं।

मैं वही कर रहा हूं जो गलत, कठिन तरीका लगता है और बस एक मान को एक-एक करके जोबजेक्ट से निकालकर स्ट्रिंग को वांछित वर्ग की संपत्ति में बदलना है।

JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);

MyAccount.EmployeeID = (string)o["employeeid"][0];

JSON संरचना को C # वर्ग में शामिल करने और JSON स्रोत से संभव लापता डेटा को संभालने का सबसे अच्छा तरीका क्या है?

मेरी कक्षा के रूप में परिभाषित किया गया है:

  public class MyAccount
  {

    [JsonProperty(PropertyName = "username")]
    public string UserID { get; set; }

    [JsonProperty(PropertyName = "givenname")]
    public string GivenName { get; set; }

    [JsonProperty(PropertyName = "sn")]
    public string Surname { get; set; }

    [JsonProperty(PropertyName = "passwordexpired")]
    public DateTime PasswordExpire { get; set; }

    [JsonProperty(PropertyName = "primaryaffiliation")]
    public string PrimaryAffiliation { get; set; }

    [JsonProperty(PropertyName = "affiliation")]
    public string[] Affiliation { get; set; }

    [JsonProperty(PropertyName = "affiliationstatus")]
    public string AffiliationStatus { get; set; }

    [JsonProperty(PropertyName = "affiliationmodifytimestamp")]
    public DateTime AffiliationLastModified { get; set; }

    [JsonProperty(PropertyName = "employeeid")]
    public string EmployeeID { get; set; }

    [JsonProperty(PropertyName = "accountstatus")]
    public string AccountStatus { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpiration")]
    public DateTime AccountStatusExpiration { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpmaxdate")]
    public DateTime AccountStatusExpirationMaxDate { get; set; }

    [JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
    public DateTime AccountStatusModified { get; set; }

    [JsonProperty(PropertyName = "accountstatusexpnotice")]
    public string AccountStatusExpNotice { get; set; }

    [JsonProperty(PropertyName = "accountstatusmodifiedby")]
    public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }

    [JsonProperty(PropertyName = "entrycreatedate")]
    public DateTime EntryCreatedate { get; set; }

    [JsonProperty(PropertyName = "entrydeactivationdate")]
    public DateTime EntryDeactivationDate { get; set; }

  }

और पार्स करने के लिए JSON का एक नमूना है:

{
    "givenname": [
        "Robert"
    ],
    "passwordexpired": "20091031041550Z",
    "accountstatus": [
        "active"
    ],
    "accountstatusexpiration": [
        "20100612000000Z"
    ],
    "accountstatusexpmaxdate": [
        "20110410000000Z"
    ],
    "accountstatusmodifiedby": {
        "20100214173242Z": "tdecker",
        "20100304003242Z": "jsmith",
        "20100324103242Z": "jsmith",
        "20100325000005Z": "rjones",
        "20100326210634Z": "jsmith",
        "20100326211130Z": "jsmith"
    },
    "accountstatusmodifytimestamp": [
        "20100312001213Z"
    ],
    "affiliation": [
        "Employee",
        "Contractor",
        "Staff"
    ],
    "affiliationmodifytimestamp": [
        "20100312001213Z"
    ],
    "affiliationstatus": [
        "detached"
    ],
    "entrycreatedate": [
        "20000922072747Z"
    ],
    "username": [
        "rjohnson"
    ],
    "primaryaffiliation": [
        "Staff"
    ],
    "employeeid": [
        "999777666"
    ],
    "sn": [
        "Johnson"
    ]
}

जवाबों:


277

उपयोग

var rootObject =  JsonConvert.DeserializeObject<RootObject>(string json);

JSON 2 C # पर अपनी कक्षाएं बनाएं


Json.NET डॉक्यूमेंटेशन: Json.NET के साथ JSON को सीरियलाइज़ और डिस्क्रिअलाइज़ करना


32
विजुअल स्टूडियो में एडिट-पेस्ट स्पेशल मेनू में क्लास विकल्प के रूप में एक पेस्ट JSON भी है।
जोनाथन एलन

76

क्या आपने जेनेरिक DeserializeObject पद्धति का उपयोग करने की कोशिश की है?

JsonConvert.DeserializeObject<MyAccount>(myjsondata);

JSON डेटा के किसी भी लापता फ़ील्ड को केवल NULL छोड़ दिया जाना चाहिए।

अपडेट करें:

यदि JSON स्ट्रिंग एक सरणी है, तो यह प्रयास करें:

var jarray = JsonConvert.DeserializeObject<List<MyAccount>>(myjsondata);

jarrayतब ए होना चाहिए List<MyAccount>

अन्य अद्यतन:

अपवाद जो आप प्राप्त कर रहे हैं वह वस्तुओं की एक सरणी के अनुरूप नहीं है- मुझे लगता है कि धारावाहिक को आपकी शब्दकोश-टाइप की गई accountstatusmodifiedbyसंपत्ति में समस्या हो रही है ।

accountstatusmodifiedby संपत्ति को क्रमांकन से बाहर करने का प्रयास करें और देखें कि क्या मदद करता है। यदि ऐसा होता है, तो आपको अलग से उस संपत्ति का प्रतिनिधित्व करने की आवश्यकता हो सकती है।

प्रलेखन: Serializing और JSON.NET के साथ JSON का वर्णन करना


धन्यवाद। हालाँकि मुझे "System.String 'टाइप में JSON एरे को डिसेर्बलाइज नहीं किया जा सकता।" जब यह (उदाहरण के लिए) JSON givenname एरे को श्रेणी में दिए जाने की अनुमति देने की कोशिश कर रहा है। JSON की विशेषताएँ जिन्हें मैंने C # वर्ग में स्ट्रिंग के रूप में परिभाषित किया है, वे केवल एकल तत्व सरणियाँ हैं। यही कारण है कि मैंने एक-एक करके मूल्यों को चुनना शुरू कर दिया क्योंकि मैं deserialize प्रक्रिया के दौरान इस तरह के मुद्दे पर भाग गया। अन्य जादू है कि मैं देख रहा हूँ?

इसलिए ... DateTime AccountStatusExpiration(उदाहरण के लिए) कोड में परिभाषित के रूप में अशक्त नहीं है। इसे अशक्त बनाने में क्या लगेगा? बस DateTimeकरने के लिए बदल DateTime??
हमीश ग्रुबीजन

50

उत्तर https://stackoverflow.com/a/10718128/776476 से पुन: प्रस्तुत किया गया

आप dynamicचीजों को आसान बनाने के लिए C # प्रकार का उपयोग कर सकते हैं । यह तकनीक री-फैक्टरिंग को भी सरल बनाती है क्योंकि यह मैजिक-स्ट्रिंग्स पर निर्भर नहीं करता है।

Json

jsonनीचे स्ट्रिंग एक http API कॉल से एक सरल प्रतिक्रिया है और यह दो गुण परिभाषित करता है: Idऔर Name

{"Id": 1, "Name": "biofractal"}

सी#

JsonConvert.DeserializeObject<dynamic>()इस स्ट्रिंग को डायनेमिक प्रकार में डिसेरिएलाइज़ करने के लिए उपयोग करें और फिर सामान्य तरीके से इसके गुणों को एक्सेस करें।

var results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;

नोट : न्यूटन सॉफ्ट असेंबली के लिए NuGet लिंक http://nuget.org/packages/newtonsoft.json है । जोड़ना न भूलें: using Newtonsoft.Json;उन वर्गों तक पहुँचने के लिए।


7
<गतिशील> के उपयोग से प्यार करें। हालाँकि, मुझे यह काम करने के लिए करना पड़ा: परिणाम ["Id"]। मूल्य और परिणाम ["नाम"]। मान
fredw

1
यद्यपि डायनेमिक एक अच्छा विकल्प है, उपरोक्त उदाहरण 'मैजिक स्ट्रिंग्स' का उपयोग नहीं कर रहे हैं, बल्कि इसके बजाय दृढ़ता से टाइप किए गए जेनेरिक का उपयोग कर रहे हैं, जो सामान्य वीएस रीफैक्टरिंग तकनीकों के दौरान अपडेट किए जाते हैं (जब तक कि एमवीसी में एक दृश्य के अंदर जो इस प्रश्न के दायरे से बाहर है)।
gcoleman0828

4
आपके पास अभी भी 'मैजिक स्ट्रिंग्स' हैं, वे अब केवल डायनामिक के उपयोग से छिपे हुए हैं!
इयान रिंगरोस

दरअसल, बायोफ्रैक्टल के पास "मैरिंग स्ट्रिंग्स" के रूप में "मैजिक स्ट्रिंग्स" है। द्वारा लौटाए गए डायनामिक ऑब्जेक्ट की DeserializeObject<dynamic>परिभाषा "टाइप-चेक" नहीं है। तो निम्नलिखित पंक्तियों results.Idऔर results.Nameसंकलन-समय पर सत्यापित नहीं किया जा सकता है। इसके बजाय रन-टाइम पर कोई त्रुटि होगी। इस तरह के रूप में एक जोरदार टाइप कॉल के साथ इसके विपरीत DeserializeObject<List<MyAccount>>। संकलन-समय पर उन संपत्तियों के संदर्भ की पुष्टि की जा सकती है। का उपयोग dynamic, हालांकि यह सुविधाजनक हो सकता है, संपत्ति के नाम के रूप में "जादू के तार" का परिचय देता है; मजबूती IMHO में कमी।
टूलमेकरसैट

8

आप उपयोग कर सकते हैं:

JsonConvert.PopulateObject(json, obj);

यहाँ: jsonjson स्ट्रिंग objहै, लक्ष्य ऑब्जेक्ट है। देखें: उदाहरण

नोट: PopulateObject()obj की सूची डेटा को नहीं मिटाएगा, के बाद Populate(), obj'sसूची के सदस्य में json स्ट्रिंग से अपना मूल डेटा और डेटा होगा


2
यह PopulateObject है - पॉप्युलेट ऑब्जेक्ट मॉडल में नहीं है।
एमोक

1
यह मेरे लिए सही काम किया! मैं ऐसे मुद्दे रख रहा था जहां मेरे पास एक बहुत ही जटिल JSON स्ट्रिंग थी, जब मैंने इसे C # ऑब्जेक्ट में डालने का प्रयास किया, तो 'NotNull' के रूप में चिह्नित कुछ भी ऑब्जेक्ट से गायब हो जाएगा, भले ही यह JSON स्ट्रिंग में मौजूद था जिसके साथ शुरू करना था। बहुत अजीब। मैंने इस पद्धति का उपयोग किया और यह सही काम किया!
jward01

3

Bbant के जवाब से दूर, यह एक दूरस्थ URL से JSON को डिसेर्लाइज़ करने के लिए मेरा पूर्ण समाधान है।

using Newtonsoft.Json;
using System.Net.Http;

namespace Base
{
    public class ApiConsumer<T>
    {
        public T data;
        private string url;

        public CalendarApiConsumer(string url)
        {
            this.url = url;
            this.data = getItems();
        }

        private T getItems()
        {
            T result = default(T);
            HttpClient client = new HttpClient();

            // This allows for debugging possible JSON issues
            var settings = new JsonSerializerSettings
            {
                Error = (sender, args) =>
                {
                    if (System.Diagnostics.Debugger.IsAttached)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
            };

            using (HttpResponseMessage response = client.GetAsync(this.url).Result)
            {
                if (response.IsSuccessStatusCode)
                {
                    result = JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result, settings);
                }
            }
            return result;
        }
    }
}

उपयोग इस तरह होगा:

ApiConsumer<FeedResult> feed = new ApiConsumer<FeedResult>("http://example.info/feeds/feeds.aspx?alt=json-in-script");

Xamasoft JSON क्लास जेनरेटरFeedResult का उपयोग करके उत्पन्न वर्ग कहां है

यहां मेरे द्वारा उपयोग की गई सेटिंग्स का एक स्क्रीनशॉट है, जो अजीब संपत्ति के नामों की अनुमति देता है, जो वेब संस्करण के लिए जिम्मेदार नहीं हो सकता है।

Xamasoft JSON क्लास जेनरेटर


1

मैंने पाया कि मैंने अपनी वस्तु को गलत तरीके से बनाया है। मैंने JSON से अपनी ऑब्जेक्ट क्लास बनाने के लिए http://json2csharp.com/ का उपयोग किया । एक बार जब मुझे सही ओजेक्ट मिला तो मैं बिना किसी मुद्दे के कास्ट करने में सक्षम था। नॉर्बिट, नॉब गलती। सोचा था कि यदि आपके पास एक ही मुद्दा है तो मैं इसे जोड़ दूंगा।


1

आप आगे की जानकारी के लिए कक्षा के कुछ जनरेटर ऑनलाइन जाँचने का प्रयास कर सकते हैं। हालाँकि, मेरा मानना ​​है कि कुछ उत्तर उपयोगी रहे हैं। यहाँ मेरा दृष्टिकोण उपयोगी हो सकता है।

निम्नलिखित कोड को एक गतिशील विधि को ध्यान में रखकर बनाया गया था।

dynObj = (JArray) JsonConvert.DeserializeObject(nvm);

foreach(JObject item in dynObj) {
 foreach(JObject trend in item["trends"]) {
  Console.WriteLine("{0}-{1}-{2}", trend["query"], trend["name"], trend["url"]);
 }
}

यह कोड मूल रूप से आपको Json string में निहित सदस्यों तक पहुँचने की अनुमति देता है। वर्गों की आवश्यकता के बिना बस एक अलग तरीका। query, trendऔर urlJson स्ट्रिंग में निहित ऑब्जेक्ट हैं।

आप इस वेबसाइट का उपयोग भी कर सकते हैं । एक 100% वर्गों पर भरोसा मत करो, लेकिन आप विचार प्राप्त करते हैं।


0

मान लें कि आपका नमूना डेटा सही है, आपका givenname, और ब्रैकेट में लिपटे अन्य प्रविष्टियाँ JS में सरणियाँ हैं ... आप उन डेटा प्रकारों के लिए सूची का उपयोग करना चाहते हैं। और कहते हैं कि अकाउंटस्टैटसुम्पेक्समैडेट के लिए सूची ... मुझे लगता है कि आपके पास उदाहरण गलत तरीके से तारीखें हैं, लेकिन आपके उदाहरण में और क्या गलत है, इस तरह अनिश्चित।

यह एक पुराना पोस्ट है, लेकिन मुद्दों पर ध्यान देना चाहता है।

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