Json.net का उपयोग करते हुए डायनामिक ऑब्जेक्ट में डेसर्साइज़ जोंस ऑब्जेक्ट


426

क्या json.net का उपयोग करके किसी json deserialization से एक गतिशील वस्तु को वापस करना संभव है? मैं ऐसा कुछ करना चाहूंगा:

dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);

1
JSON json2csharp.com से C # क्लास जेनरेट करने पर विचार करें और डायनेमिक के बजाय जेनरेट क्लास का उपयोग करें
माइकल फ्रीजिम


आप सुझाव देते हैं कि स्टैकओवरफ़्लो एक प्रश्न को "बहुत पुराना" के रूप में बंद कर देता है? छह साल हो गए हैं, तब से लेकर अब तक के हर संस्करण के लिए वैध जवाब और उचित सुझाव हैं ... इतने सारे कि वे वास्तव में किसी भी अधिक उपयोगी नहीं हैं।
andrew lorien

जवाबों:


546

Json.NET हमें ऐसा करने की अनुमति देता है:

dynamic d = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");

Console.WriteLine(d.number);
Console.WriteLine(d.str);
Console.WriteLine(d.array.Count);

आउटपुट:

 1000
 string
 6

यहां प्रलेखन: LINQ to JSON with Json.NET

JObject.Parse और JArray.Parse भी देखें


36
ध्यान दें कि सरणियों के लिए वाक्य रचना है JArray.Parse
jgillich

4
हमें गतिशील शब्द का उपयोग करने की आवश्यकता क्यों है? मुझे डर नहीं है कि पहले कभी इस्तेमाल नहीं किया गया: डी
मॉन्स्टरमोरपीजी

3
VB.Net में आपको करने की आवश्यकता हैDim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
ilans

2
@MonsterMMORPG आपको होना चाहिए :) गतिशील लगभग हर परिस्थितियों में एक विरोधी पैटर्न है, लेकिन, हर अब और फिर, आपके पास एक ऐसी स्थिति हो सकती है जहां इसका उपयोग करना उचित है।
प्लुक

4
Newtonsoft.Json 8.0.3 (.NET 4.5.2) के साथ: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException हुई HResult = -2146233088 संदेश = 'Newtonsoft.Json.Linq .JOject' में 'संख्या' के लिए परिभाषा नहीं है। स्रोत = Microsoft .CSharp StackTrace: Microsoft.CSharp.RuntimeBinder.untimeBinderController.SubmitError (CError pError) पर
user4698855

107

Json.NET 4.0 रिलीज 1 के रूप में, मूल गतिशील समर्थन है:

[Test]
public void DynamicDeserialization()
{
    dynamic jsonResponse = JsonConvert.DeserializeObject("{\"message\":\"Hi\"}");
    jsonResponse.Works = true;
    Console.WriteLine(jsonResponse.message); // Hi
    Console.WriteLine(jsonResponse.Works); // True
    Console.WriteLine(JsonConvert.SerializeObject(jsonResponse)); // {"message":"Hi","Works":true}
    Assert.That(jsonResponse, Is.InstanceOf<dynamic>());
    Assert.That(jsonResponse, Is.TypeOf<JObject>());
}

और, ज़ाहिर है, वर्तमान संस्करण प्राप्त करने का सबसे अच्छा तरीका NuGet है।

टिप्पणी को संबोधित करने के लिए अद्यतन (11/12/2014):

यह पूरी तरह से ठीक काम करता है। यदि आप डिबगर में प्रकार का निरीक्षण करते हैं, तो आप देखेंगे कि मूल्य वास्तव में, गतिशील हैअंतर्निहित प्रकार एक है JObject। यदि आप प्रकार को नियंत्रित करना चाहते हैं (जैसे निर्दिष्ट करना ExpandoObject, तो ऐसा करें।

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


20
यह काम करने के लिए कभी नहीं लगता है। यह केवल एक जोबजेक्ट लौटाता है, न कि एक डायनामिक वैरिएबल।
पॉल

12
BTW, यह काम करता है: JsonConvert.DeserializeObject <ExpandoObject> (STRING); उचित अक्रमांकन साथ, तो हम JObject आदि की जरूरत नहीं है
Gutek

2
@Gutek निश्चित नहीं है कि आपका मुद्दा क्या है। क्या आपने कोड चलाया? मैंने परीक्षण में जोर दिया और एक संपत्ति जोड़ दी, जो मूल जसन में नहीं थी। डीबगर का स्क्रीनशॉट शामिल है।
डेविड पेन्डेन

1
@DavidPeden अगर आपके पास जोबजेक्ट है और आप कोशिश करेंगे कि रेजर में आपको अपवाद मिलेगा। प्रश्न डायनेमिक ऑब्जेक्ट के डीरियलाइज़ करने के बारे में था - जोबिज डायनेमिक है लेकिन इसमें "स्वयं" प्रकार होते हैं जैसे जेवल्यू आदिम प्रकार नहीं। @Model.Propअगर वापसी प्रकार JValue है तो मैं रेज़र में नाम का उपयोग नहीं कर सकता ।
गुटेक

2
यह काम करता है, लेकिन प्रत्येक गतिशील संपत्ति एक है JValue। जिसने मुझे भ्रमित कर दिया क्योंकि मैं डिबगर / तत्काल विंडो में काम कर रहा था और बस stringएस नहीं देख रहा था । डेविड इसे नीचे स्क्रीनशॉट में दिखाता है। JValueपरिवर्तनीय है, इसलिए आप बस कर सकते हैंstring m = jsonResponse.message
ल्यूक Puplett

66

यदि आप डायनेमिक के लिए बस डिस्क्राइब करते हैं तो आपको एक जेजबजेक्ट वापस मिल जाएगा। आप एक ExpandoObject का उपयोग करके जो चाहें प्राप्त कर सकते हैं।

var converter = new ExpandoObjectConverter();    
dynamic message = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);

1
परिणाम को डिक्शनरी में भी बदला जा सकता है
FindOutIslamNow

1
वास्तव में मैं क्या देख रहा था! धन्यवाद!
DarkDeny

42

मुझे पता है कि यह पुरानी पोस्ट है लेकिन JsonConvert का वास्तव में एक अलग तरीका है इसलिए यह होगा

var product = new { Name = "", Price = 0 };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, product);

23
यह एक गुमनाम प्रकार में एक जोंस पेलोड deserializing होगा, न कि एक गतिशील प्रकार। अज्ञात प्रकार और गतिशील प्रकार अलग-अलग चीजें हैं, और मुझे विश्वास नहीं है कि यह पूछे गए प्रश्न को संबोधित करता है।
jrista

1
क्या दो चर का उपयोग करना आवश्यक है? दूसरे कथन में पहले एक का पुन: उपयोग क्यों नहीं?
RenniePet

21

हाँ आप इसे JsonConvert.DeserializeObject का उपयोग करके कर सकते हैं। ऐसा करने के लिए, बस सरल करना है:

dynamic jsonResponse = JsonConvert.DeserializeObject(json);
Console.WriteLine(jsonResponse["message"]);

1
JsonConvertएक विधि कहा जाता है शामिल नहीं है Deserialize
कर सकते हैं Poyrazoğlu 17

यह सिर्फ DeserializeObject होना चाहिए, लेकिन यह स्वीकृत उत्तर होना चाहिए IMO
superjugy

21

नोट: जिस समय मैंने 2010 में इस प्रश्न का उत्तर दिया था, उस समय बिना किसी प्रकार के डिस्क्राइब करने का कोई तरीका नहीं था, इसने आपको वास्तविक वर्ग को परिभाषित किए बिना डीरिएराइज करने की अनुमति दी और एक अनाम वर्ग को डिसेरिएलाइजेशन करने की अनुमति दी।


आपको डीसर्लाइज़ करने के लिए कुछ प्रकार की आवश्यकता है। आप की तर्ज पर कुछ कर सकते हैं:

var product = new { Name = "", Price = 0 };
dynamic jsonResponse = JsonConvert.Deserialize(json, product.GetType());

मेरा उत्तर JSON धारावाहिक में .NET 4.0 के निर्माण के लिए एक समाधान पर आधारित है। अनाम प्रकारों के deserialize के लिए लिंक यहाँ है:

http://blogs.msdn.com/b/alexghi/archive/2008/12/22/using-anonymous-types-to-deserialize-json-data.aspx


मैं तुम्हारे साथ हूँ, मुझे नहीं पता कि लोग इसे क्यों वोट करते हैं, अगर कोई भी तुम्हें खुश कर सकता है .. तो कृपया क्यों समझाएं?
PEO

18
वे नीच हैं क्योंकि सवाल एक प्रकार के बिना deserializing के बारे में है।
richard

4
उत्तर 2010 में इसे लिखने के समय मान्य था जब कोई अन्य समाधान नहीं था। यह JSON.NET में समर्थन आने तक छोटी अवधि के लिए स्वीकृत उत्तर भी था।
फिल

1
यह एक गतिशील वस्तु का उत्पादन नहीं करता है। यह एक JObject पैदा करता है जिसे आप एक डायनामिक के रूप में संदर्भित करते हैं। लेकिन इसके अंदर अभी भी एक जोबजेक्ट है।
ghostbust555

5

यदि आप पुराने संस्करण के साथ JSON.NET का उपयोग करते हैं, जो JObject नहीं था।

JSON से डायनामिक ऑब्जेक्ट बनाने का यह एक और सरल तरीका है: https://github.com/chsword/jdynamic

NuGet इंस्टॉल करें

PM> Install-Package JDynamic

सदस्य तक पहुंचने के लिए स्ट्रिंग इंडेक्स का उपयोग करना जैसे:

dynamic json = new JDynamic("{a:{a:1}}");
Assert.AreEqual(1, json["a"]["a"]);

परीक्षण का मामला

और आप इस उपयोग को निम्नानुसार कर सकते हैं:

सीधे मूल्य प्राप्त करें

dynamic json = new JDynamic("1");

//json.Value

2. सदस्य को json ऑब्जेक्ट में रखें

dynamic json = new JDynamic("{a:'abc'}");
//json.a is a string "abc"

dynamic json = new JDynamic("{a:3.1416}");
//json.a is 3.1416m

dynamic json = new JDynamic("{a:1}");
//json.a is integer: 1

3.IEnumerable

dynamic json = new JDynamic("[1,2,3]");
/json.Length/json.Count is 3
//And you can use json[0]/ json[2] to get the elements

dynamic json = new JDynamic("{a:[1,2,3]}");
//json.a.Length /json.a.Count is 3.
//And you can use  json.a[0]/ json.a[2] to get the elements

dynamic json = new JDynamic("[{b:1},{c:1}]");
//json.Length/json.Count is 2.
//And you can use the  json[0].b/json[1].c to get the num.

अन्य

dynamic json = new JDynamic("{a:{a:1} }");

//json.a.a is 1.

2

हाँ यह संभव है। मैं हर समय ऐसा करता रहा हूं।

dynamic Obj = JsonConvert.DeserializeObject(<your json string>);

यह गैर देशी प्रकार के लिए थोड़ा मुश्किल है। मान लीजिए कि आपके ओब्ज के अंदर एक क्लासए और क्लासबी ऑब्जेक्ट्स हैं। वे सभी जोबजेक्ट में परिवर्तित हो गए हैं। आपको क्या करने की आवश्यकता है:

ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.