2008-10-14 11 views
8

चूंकि ऑब्जेक्ट प्रारंभकर्ता जेएसओएन के समान हैं, और अब .NET में बेनामी प्रकार हैं। JSON जैसे स्ट्रिंग लेने में सक्षम होना अच्छा होगा, और जेएसओएन स्ट्रिंग का प्रतिनिधित्व करने वाला एक अनाम ऑब्जेक्ट बनाएं।क्या आप JSON से .NET में ऑब्जेक्ट इंस्टेंस को इंस्टेंट कर सकते हैं?

उपयोग ऑब्जेक्ट initializers एक बेनामी प्रकार बनाने के लिए:

var person = new { 
    FirstName = "Chris", 
    LastName = "Johnson" 
}; 

यह गज़ब का यदि आप ऑब्जेक्ट प्रारंभकर्ता कोड (अधिमानतः JSON की तरह कुछ) के एक स्ट्रिंग प्रतिनिधित्व में पारित एक बेनामी का एक उदाहरण बनाने के लिए सकता है उस डेटा के साथ टाइप करें।

मुझे नहीं पता कि यह संभव है, क्योंकि सी # गतिशील नहीं है, और संकलक वास्तव में ऑब्जेक्ट इनलाइलाइज़र को d Anonymous Type into strongly typed code that can run. This is explained in इस आलेख में परिवर्तित करता है।

शायद JSON लेने और इसके साथ एक कुंजी/मूल्य शब्दकोश बनाने की कार्यक्षमता सर्वोत्तम काम करेगी।

मुझे पता है कि आप किसी ऑब्जेक्ट को .NET में जेएसओएन को क्रमबद्ध/deserializer कर सकते हैं, लेकिन जो भी मैं देख रहा हूं वह एक ऐसी वस्तु बनाने का एक तरीका है जो अनिवार्य रूप से ढीला टाइप किया गया है, इसी प्रकार जावास्क्रिप्ट कैसे काम करता है।

क्या कोई भी .NET में ऐसा करने के लिए सबसे अच्छा समाधान जानता है?

अद्यतन: मैं यह क्यों पूछ रहा हूं के संदर्भ को स्पष्ट करने के लिए ... मैं सोच रहा था कि कैसे सी # भाषा स्तर पर जेएसओएन का बेहतर समर्थन कर सकता है (संभवतः) और मैं उन तरीकों के बारे में सोचने की कोशिश कर रहा था जो इसे किया जा सकता है आज, वैचारिक कारणों के लिए। तो, मैंने सोचा कि मैं इसे एक चर्चा शुरू करने के लिए यहां पोस्ट करूंगा।

उत्तर

6

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

T deserialize<T>(string jsonStr, T obj) { /* ... */} 

var jsonString = "{FirstName='Chris', LastName='Johnson, Other='unused'}"; 
var person  = deserialize(jsonString, new {FirstName="",LastName=""}); 
var x   = person.FirstName; //strongly-typed 
+0

+1, गंदे, लेकिन वर्तमान में ओपी चाहता है जो करने का एकमात्र तरीका है। – user7116

+0

बहुत अच्छा, यह एक तरीका है जिस पर मैंने नहीं सोचा था। –

+0

क्या लगता है कि उत्तर अब से होगा # सी गतिशील प्रकारों का समर्थन करता है –

0

इसके लिए आवेदन क्या है?

मैं कुछ कारणों से इस सड़क पर नहीं जाऊंगा।

  • पहला; इसके प्रतिबिंब का उपयोग करके बहुत सारे समर्थन कोड की आवश्यकता हो सकती है और इस तरह की पारदर्शी विधि बनाने के लिए आप जिस बारे में बात कर रहे हैं।

  • दूसरा, जैसा कि आपने कहा था, सी # दृढ़ता से टाइप की गई भाषा है और इन चीजों को किसी कारण के लिए भाषा विनिर्देश से बाहर रखा गया था।

  • तीसरा, ऐसा करने के लिए ओवरहेड इसके लायक नहीं होगा। याद रखें कि वेब पेज (विशेष रूप से AJAX क्वेरी) वास्तव में तेज़ होना चाहिए या यह उद्देश्य को हरा देता है। यदि आप आगे बढ़ते हैं और सी # और जावास्क्रिप्ट के बीच अपनी वस्तुओं को क्रमबद्ध करने में 50% खर्च करते हैं तो आपको एक समस्या है।

मेरे समाधान एक वर्ग है कि सिर्फ एक शब्दकोश समाहित बनाने के लिए हो सकता है और है कि एक ctor तर्क के रूप में JSON स्ट्रिंग लेता है। फिर बस उस वर्ग को प्रत्येक प्रकार की JSON क्वेरी के लिए बढ़ाएं जिसे आप संभालना चाहते हैं। यह एक दृढ़ता से टाइप और तेज समाधान होगा लेकिन अभी भी विस्तारशीलता और उपयोग में आसानी बनाए रखेगा। नकारात्मकता यह है कि प्रति प्रकार के JSON अनुरोध लिखने के लिए और कोड है।

:)

5

आप JSON.net की जांच करनी चाहिए परियोजना:

http://james.newtonking.com/pages/json-net.aspx

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

1

आप एक विधि ** से एक गुमनाम प्रकार वापस नहीं लौट सकते, तो एक "rehydrated" गुमनाम प्रकार के अस्तित्व विधि है जिसमें यह rehydrated है करने के लिए सीमित किया जाएगा। व्यर्थ प्रकार की तरह।

** आप इसे एक ऑब्जेक्ट के रूप में वापस कर सकते हैं (जिसके लिए इसकी गुणों का उपयोग करने के लिए प्रतिबिंब की आवश्यकता होती है) या आप "उदाहरण के द्वारा इसे कास्ट कर सकते हैं", जो व्यर्थ है, क्योंकि यह अतिरिक्त कदम उठाता है और इसका मतलब है पहले से ही पता क्या वस्तु के प्रकार की तरह दिखना चाहिए, तो क्यों सिर्फ एक वस्तु बना सकते हैं और पहली जगह में इसे भर नहीं?

4

मैं एक अपेक्षाकृत कम विधि है कि JSON पार्स और एक नाम/मान शब्दकोश कि जावास्क्रिप्ट में वास्तविक वस्तु की तरह ही पहुँचा जा सकता है वापस आ जाएगी लिखा था।

यहाँ नीचे दी गई विधि का एक नमूना उपयोग है:

var obj = ParseJsonToDictionary("{FirstName: \"Chris\", \"Address\":{Street:\"My Street\",Number:123}}"); 

// Access the Address.Number value 
object streetNumber = ((Dictionary<string, object>)obj["Address"])["Number"]; 

और, यहाँ ParseJsonToDictionary विधि के लिए कोड है:

public static Dictionary<string, object> ParseJsonToDictionary(string json) 
{ 
    var d = new Dictionary<string, object>(); 

    if (json.StartsWith("{")) 
    { 
     json = json.Remove(0, 1); 
     if (json.EndsWith("}")) 
      json = json.Substring(0, json.Length - 1); 
    } 
    json.Trim(); 

    // Parse out Object Properties from JSON 
    while (json.Length > 0) 
    { 
     var beginProp = json.Substring(0, json.IndexOf(':')); 
     json = json.Substring(beginProp.Length); 

     var indexOfComma = json.IndexOf(','); 
     string endProp; 
     if (indexOfComma > -1) 
     { 
      endProp = json.Substring(0, indexOfComma); 
      json = json.Substring(endProp.Length); 
     } 
     else 
     { 
      endProp = json; 
      json = string.Empty; 
     } 

     var curlyIndex = endProp.IndexOf('{'); 
     if (curlyIndex > -1) 
     { 
      var curlyCount = 1; 
      while (endProp.Substring(curlyIndex + 1).IndexOf("{") > -1) 
      { 
       curlyCount++; 
       curlyIndex = endProp.Substring(curlyIndex + 1).IndexOf("{"); 
      } 
      while (curlyCount > 0) 
      { 
       endProp += json.Substring(0, json.IndexOf('}') + 1); 
       json = json.Remove(0, json.IndexOf('}') + 1); 
       curlyCount--; 
      } 
     } 

     json = json.Trim(); 
     if (json.StartsWith(",")) 
      json = json.Remove(0, 1); 
     json.Trim(); 


     // Individual Property (Name/Value Pair) Is Isolated 
     var s = (beginProp + endProp).Trim(); 


     // Now parse the name/value pair out and put into Dictionary 
     var name = s.Substring(0, s.IndexOf(":")).Trim(); 
     var value = s.Substring(name.Length + 1).Trim(); 

     if (name.StartsWith("\"") && name.EndsWith("\"")) 
     { 
      name = name.Substring(1, name.Length - 2); 
     } 

     double valueNumberCheck; 
     if (value.StartsWith("\"") && value.StartsWith("\"")) 
     { 
      // String Value 
      d.Add(name, value.Substring(1, value.Length - 2)); 
     } 
     else if (value.StartsWith("{") && value.EndsWith("}")) 
     { 
      // JSON Value 
      d.Add(name, ParseJsonToDictionary(value)); 
     } 
     else if (double.TryParse(value, out valueNumberCheck)) 
     { 
      // Numeric Value 
      d.Add(name, valueNumberCheck); 
     } 
     else 
      d.Add(name, value); 
    } 

    return d; 
} 

मैं इस विधि में एक छोटे से किसी न किसी तरह हो सकता है, और यह कर सकता है शायद थोड़ा सा अनुकूलित किया जा सकता है, लेकिन यह पहला मसौदा है और यह सिर्फ काम करता है।

इसके अलावा

, इससे पहले कि आप नियमित अभिव्यक्ति का उपयोग नहीं कर इसके बारे में शिकायत करते हैं, ध्यान रखें कि हर कोई वास्तव में नियमित अभिव्यक्ति समझता में रखने के लिए, और इस तरह से और अधिक कठिन यदि आवश्यक हो तो दूसरों को ठीक करने के लिए में होगा यह लेखन। इसके अलावा, मैं वर्तमान में नियमित अभिव्यक्ति को अच्छी तरह से नहीं जानता, और स्ट्रिंग पार्सिंग बस आसान था।

+0

@ जेसन स्ट्रिंग को पार्स करने के लिए क्रिस को इस तरह के एक अच्छे कोड के लिए धन्यवाद –

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

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