2012-03-06 8 views
79

JSON मानों को पुनर्प्राप्त करने के लिए सबसे अच्छा अभ्यास क्या है जो Json.NET का उपयोग कर सी # में भी मौजूद नहीं हो सकता है?जेटीकेन से मूल्य प्राप्त करें जो मौजूद नहीं हो सकता है (सर्वोत्तम प्रथाओं)

अभी मैं एक JSON प्रदाता से निपट रहा हूं जो JSON लौटाता है जिसमें कभी-कभी कुछ महत्वपूर्ण/मान जोड़े होते हैं, और कभी-कभी नहीं। मैं (उदाहरण के लिए एक डबल प्राप्त करने के लिए) मेरे मूल्यों को प्राप्त करने के लिए इस पद्धति का उपयोग किया गया है (शायद गलत तरीके से):

if(null != jToken["width"]) 
    width = double.Parse(jToken["width"].ToString()); 
else 
    width = 100; 

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

public static T GetValue<T>(this JToken jToken, string key, 
          T defaultValue = default(T)) 
{ 
    T returnValue = defaultValue; 

    if (jToken[key] != null) 
    { 
     object data = null; 
     string sData = jToken[key].ToString(); 

     Type type = typeof(T); 

     if (type is double) 
      data = double.Parse(sData); 
     else if (type is string) 
      data = sData; 

     if (null == data && type.IsValueType) 
      throw new ArgumentException("Cannot parse type \"" + 
       type.FullName + "\" from value \"" + sData + "\""); 

     returnValue = (T)Convert.ChangeType(data, 
      type, CultureInfo.InvariantCulture); 
    } 

    return returnValue; 
} 

और यहाँ विस्तार विधि का उपयोग का एक उदाहरण है:

width = jToken.GetValue<double>("width", 100); 

Btw, कृपया माफ कर क्या वास्तव में एक मूक सवाल हो सकता है, क्योंकि यह कुछ की तरह लगता है कि वहाँ एक होना चाहिए के लिए फ़ंक्शन में बनाया गया ... मैंने Google और Json.NET दस्तावेज़ों का प्रयास किया, हालांकि मैं या तो अक्षम हूं मेरे प्रश्न का हल ढूंढ नहीं रहा है या यह दस्तावेज़ीकरण में स्पष्ट नहीं है।

+0

मैं इसे थोड़ी देर हो चुकी है, लेकिन आप नीचे –

उत्तर

150

यह जेनेरिक विधि Value() के लिए बहुत कुछ है।

width = jToken.Value<double?>("width") ?? 100; 
+2

धन्यवाद @svick 'GetValue' के इस सरलीकृत संस्करण की कोशिश करना चाहते हो सकता है! यही वही है जो मैं ढूंढ रहा था। जैसा कि मुझे संदेह था कि यह कुछ सरल, समान, और पहले से ही जगह पर है।* चेहरा हथेली * –

+3

यह एक विस्तार विधि है। –

+1

@ पॉलहाज़ेन, यह बुरा नहीं है ... आपने बस पहिया को फिर से बदल दिया है। – devinbost

12

मैं GetValue

public static T GetValue<T>(this JToken jToken, string key, T defaultValue = default(T)) 
{ 
    dynamic ret = jToken[key]; 
    if (ret == null) return defaultValue; 
    if (ret is JObject) return JsonConvert.DeserializeObject<T>(ret.ToString()); 
    return (T)ret; 
} 

इस तरह नीचे के रूप में लिखते थे आप न केवल का मूल्य प्राप्त कर सकते हैं: आप वास्तव में व्यवहार आप अगर आप इसे व्यर्थ मूल्य प्रकार के साथ गठबंधन करना चाहते हैं और ?? ऑपरेटर मिल बुनियादी प्रकार लेकिन जटिल वस्तुओं भी। यहां एक नमूना

public class ClassA 
{ 
    public int I; 
    public double D; 
    public ClassB ClassB; 
} 
public class ClassB 
{ 
    public int I; 
    public string S; 
} 

var jt = JToken.Parse("{ I:1, D:3.5, ClassB:{I:2, S:'test'} }"); 

int i1 = jt.GetValue<int>("I"); 
double d1 = jt.GetValue<double>("D"); 
ClassB b = jt.GetValue<ClassB>("ClassB"); 
+0

यह बहुत अच्छा है, लेकिन मुझे चिंताओं को अलग करना पसंद है जो केवल सरल डेटा प्रकार प्राप्त करते हैं। हालांकि जेएसओएन पार्सिंग की बात आती है तो उस अलगाव की धारणा थोड़ी धुंधली होती है। चूंकि मैं एक पर्यवेक्षक/अवलोकन योग्य मॉडल (एमवीवीएम के साथ भी) को लागू करता हूं, इसलिए मैं अपने सभी पार्सिंग को एक ही स्थान पर रखना चाहता हूं, और इसे सरल रखना (इसका हिस्सा भी मेरे पास लौटाए गए डेटा की अप्रत्याशितता है)। –

+0

@ पॉलहाज़ेन मैं यह नहीं कह सकता कि मैं आपको समझता हूं। आपका प्रश्न 'JSON मानों को पुनर्प्राप्त करना था जो कि अस्तित्व में भी नहीं हो सकता है' और मैंने जो भी प्रस्तावित किया था वह आपकी 'GetValue' विधि को बदलना था। मुझे लगता है कि यह काम करता है कि आप कैसे –

+0

चाहते हैं उम्मीद है कि मैं इस बार थोड़ा और स्पष्ट हो सकता हूं। आपकी विधि बहुत अच्छी तरह से काम करती है, और जो भी मैं चाहता हूं उसे पूरा कर लेती हूं। हालांकि, मेरे प्रश्न में अधिक संदर्भ नहीं बताया गया है कि मैं जिस विशेष कोड पर काम कर रहा हूं वह कोड है जिसे मैं अत्यधिक हस्तांतरणीय बनाना चाहता हूं। हालांकि यह तर्कसंगत है कि आपकी विधि रास्ते में आती है, यह GetValue से वस्तुओं को deserialize करने की क्षमता का परिचय देता है, जो एक पैटर्न है जो मैं अपने कोड को एक ऐसे मंच पर ले जाने के लिए टालना चाहता हूं जिसमें एक बेहतर JSON पार्सर है (कहें, Win8 उदाहरण के लिए)। तो, मैंने जो पूछा, उसके लिए, हाँ, आपका कोड सही होगा। –

2

आप बस टाइपकास्ट सकता है, और यह आप हैं, उदाहरण के लिए रूपांतरण करना होगा

var with = (double?) jToken[key] ?? 100; 

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

3

यहाँ आप कैसे जांच कर सकते हैं टोकन मौजूद है:

if (jobject["Result"].SelectToken("Items") != null) { ... } 

यह जाँच करता है, तो "आइटम" "परिणाम" में मौजूद है।

if (jobject["Result"]["Items"] != null) { ... } 
0

TYPE variable = jsonbody["key"]?.Value<TYPE>() ?? DEFAULT_VALUE;

उदहारण के लिए:

यह एक काम कर नहीं उदाहरण है कि अपवाद का कारण बनता है

bool attachMap = jsonbody["map"]?.Value<bool>() ?? false;

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