2012-12-04 20 views
17

मैं एक डब्ल्यूसीएफ सेवा का उपभोग कर रहा हूं जो 'डी' रूट तत्व के अंदर जेएसओएन परिणाम लपेटता है। JSON उत्तर इस तरह दिखता है:जेएसओएन deserializing - मूल तत्व को अनदेखा कैसे करें?

{"d":[ 
    { 
    "__type":"DiskSpaceInfo:#Diagnostics.Common", 
    "AvailableSpace":38076567552, 
    "Drive":"C:\\", 
    "TotalSpace":134789197824 
    }, 
    { 
    "__type":"DiskSpaceInfo:#Diagnostics.Common", 
    "AvailableSpace":166942183424, 
    "Drive":"D:\\", 
    "TotalSpace":185149157376 
    } 
]} 

मैं गतिशील लेखन का उपयोग नहीं करना चाहते हैं, मैं अपने वर्ग Diagnostics.Common.DiskSpaceInfo है कि मैं जब deserializing उपयोग करना चाहते हैं।

मैं जेसन.NET (नेटवॉन्सॉफ्ट JSON) का उपयोग कर रहा हूं।

सवाल यह है कि रूट तत्व ('डी' तत्व) को अनदेखा करने के लिए इसे कैसे बताना है और अंदर क्या है।

DiskSpaceInfo[] result = JsonConvert.DeserializeAnonymousType(json, new 
    { 
     d = new DiskSpaceInfo[0] 
    }).d; 

यह वास्तव में काम करता है लेकिन मैं इसे बहुत पसंद नहीं है:

सबसे अच्छा समाधान मैं अब तक है एक गुमनाम प्रकार का उपयोग करने के लिए है। क्या कोई और तरीका है? क्या मैं चाहते हैं की तरह कुछ:

DiskSpaceInfo[] result = JsonConvert.Deserialize(json, skipRoot: true); 

या ऐसा ही कुछ ...

+0

+1 क्योंकि मैं अपने गुमनाम प्रकार समाधान की तरह। –

+0

संबंधित प्रश्न जो पूछता है कि मध्यवर्ती 'जेटोकन' को पार्स किए बिना इसे कैसे किया जाए: [JSON.NET एक विशिष्ट संपत्ति को deserialize] (https://stackoverflow.com/questions/19438472/json-net-deserialize-a- विशिष्ट- संपत्ति)। – dbc

उत्तर

16

यदि आपको पता है कि इस मामले में "डी" की तरह क्या खोजना है जो रूट नोड है तो आप निम्न कार्य कर सकते हैं।

JObject jo = JObject.Parse(json); 
DiskSpaceInfo[] diskSpaceArray = jo.SelectToken("d", false).ToObject<DiskSpaceInfo[]>(); 

आप बस रूट वर्ग है जिसे आप नहीं जानते कि तुम "@Giu डू" समाधान का उपयोग कर सकते केवल आपके Console.Write(test2);

 JObject o = JObject.Parse(json); 
     if (o != null) 
     { 
      var test = o.First; 
      if (test != null) 
      { 
       var test2 = test.First; 
       if (test2 != null) 
       { 
        DiskSpaceInfo[] diskSpaceArray = test2.ToObject<DiskSpaceInfo[]>(); 
       } 
      } 
     } 
+0

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

1

तक Newtonsoft, मैं तुम्हें JSon.net का उपयोग लगता है, यहाँ मेरी हल है, मैं JSON उपलब्ध करने के लिए इस्तेमाल किया Linq इस ढांचे में:

using System; 
using Newtonsoft.Json.Linq; 

namespace JSonTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string json = @"{""d"":[ 
    { 
    ""__type"":""DiskSpaceInfo:#Diagnostics.Common"", 
    ""AvailableSpace"":38076567552, 
    ""Drive"":""C:\\"", 
    ""TotalSpace"":134789197824 
    }, 
    { 
    ""__type"":""DiskSpaceInfo:#Diagnostics.Common"", 
    ""AvailableSpace"":166942183424, 
    ""Drive"":""D:\\"", 
    ""TotalSpace"":185149157376 
    } 
]}"; 
     JObject o = JObject.Parse(json); 

     if (o != null) 
     { 
      var test = o.First; 

      if (test != null) 
      { 
       var test2 = test.First; 
       if (test2 != null) 
       { 
        Console.Write(test2); 
       } 
      } 
     } 

     Console.Read(); 

    } 
} 
} 

मैं संपत्ति पहले का इस्तेमाल किया है क्योंकि आप घ के बाद प्रथम नोड, जो json आप प्राप्त की पहली नोड है खोजने की जरूरत है।

आपको केवल एक ऐसा फ़ंक्शन बनाना है जो मुख्य को पुन: उत्पन्न करता है, यह जांचना न भूलें कि NullReferenceException से बचने के लिए ऑब्जेक्ट्स शून्य नहीं हैं या नहीं।

+0

धन्यवाद Ju Do Json.NET नामकरण के लिए, मैंने इसे मूल प्रश्न में संपादित किया। आपके समाधान के संबंध में, मैं test2 को सही प्रकार DiskSpaceInfo पर कैसे डालूं? test2 अभी भी JToken टाइप प्रकार है। –

1
के बजाय test2.ToObject<DiskSpaceInfo[]>(); उपयोग कर सकते हैं कि अनदेखी करने के लिए चाहते हैं

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

public static class JsonUtil 
{ 
    public static T Deserialize<T>(string json, bool ignoreRoot) where T : class 
    { 
     return ignoreRoot 
      ? JObject.Parse(json)?.Properties()?.First()?.Value?.ToObject<T>() 
      : JObject.Parse(json)?.ToObject<T>(); 
    } 
} 

आप इस तरह यह आह्वान होगा:

var resultA = JsonUtil.Deserialize<DiskSpaceInfo[]>(json, ignoreRoot: true); 

या

var resultB = JsonUtil.Deserialize<DiskSpaceInfoRoot>(json, ignoreRoot: false); 
संबंधित मुद्दे