JSON

2009-01-16 17 views
19

पर डेटाटेबल मुझे हाल ही में जेएसओएन के लिए एक डाटाटेबल को क्रमबद्ध करने की आवश्यकता है। जहां मैं हूं, हम अभी भी .NET 2.0 पर हैं, इसलिए मैं .NET 3.5 में JSON serializer का उपयोग नहीं कर सकता। मुझे लगा कि यह पहले किया जाना चाहिए था, इसलिए मैं differentoptions के number पर ऑनलाइन देख रहा था और found। उनमें से कुछ अतिरिक्त पुस्तकालय पर निर्भर करते हैं, जो मुझे यहां से कठिन समय तक धक्का दे रहा है। दूसरों को पहले List<Dictionary<>> में कनवर्ट करने की आवश्यकता होती है, जो थोड़ा अजीब और अनावश्यक लग रहा था। एक और स्ट्रिंग की तरह सभी मूल्यों का इलाज किया। एक कारण या किसी अन्य कारण से मैं वास्तव में उनमें से किसी के पीछे नहीं आ सकता था, इसलिए मैंने अपना खुद का रोल करने का फैसला किया, जो नीचे पोस्ट किया गया है।JSON

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

ध्यान दें कि यह क्षमता .NET 3.5 और बाद में बनाई गई है, और इसलिए आज इस कोड का उपयोग करने का एकमात्र कारण यह है कि यदि आप अभी भी .NET 2.0 तक सीमित हैं। फिर भी, JSON.Net इस तरह की चीज़ के लिए गोटो लाइब्रेरी बन गया है।

public static class JSONHelper 
{ 
    public static string FromDataTable(DataTable dt) 
    { 
     string rowDelimiter = ""; 

     StringBuilder result = new StringBuilder("["); 
     foreach (DataRow row in dt.Rows) 
     { 
      result.Append(rowDelimiter); 
      result.Append(FromDataRow(row)); 
      rowDelimiter = ","; 
     } 
     result.Append("]"); 

     return result.ToString(); 
    } 

    public static string FromDataRow(DataRow row) 
    { 
     DataColumnCollection cols = row.Table.Columns; 
     string colDelimiter = ""; 

     StringBuilder result = new StringBuilder("{");  
     for (int i = 0; i < cols.Count; i++) 
     { // use index rather than foreach, so we can use the index for both the row and cols collection 
      result.Append(colDelimiter).Append("\"") 
        .Append(cols[i].ColumnName).Append("\":") 
        .Append(JSONValueFromDataRowObject(row[i], cols[i].DataType)); 

      colDelimiter = ","; 
     } 
     result.Append("}"); 
     return result.ToString(); 
    } 

    // possible types: 
    // http://msdn.microsoft.com/en-us/library/system.data.datacolumn.datatype(VS.80).aspx 
    private static Type[] numeric = new Type[] {typeof(byte), typeof(decimal), typeof(double), 
            typeof(Int16), typeof(Int32), typeof(SByte), typeof(Single), 
            typeof(UInt16), typeof(UInt32), typeof(UInt64)}; 

    // I don't want to rebuild this value for every date cell in the table 
    private static long EpochTicks = new DateTime(1970, 1, 1).Ticks; 

    private static string JSONValueFromDataRowObject(object value, Type DataType) 
    { 
     // null 
     if (value == DBNull.Value) return "null"; 

     // numeric 
     if (Array.IndexOf(numeric, DataType) > -1) 
      return value.ToString(); // TODO: eventually want to use a stricter format. Specifically: separate integral types from floating types and use the "R" (round-trip) format specifier 

     // boolean 
     if (DataType == typeof(bool)) 
      return ((bool)value) ? "true" : "false"; 

     // date -- see http://weblogs.asp.net/bleroy/archive/2008/01/18/dates-and-json.aspx 
     if (DataType == typeof(DateTime))  
      return "\"\\/Date(" + new TimeSpan(((DateTime)value).ToUniversalTime().Ticks - EpochTicks).TotalMilliseconds.ToString() + ")\\/\""; 

     // TODO: add Timespan support 
     // TODO: add Byte[] support 

     //TODO: this would be _much_ faster with a state machine 
     //TODO: way to select between double or single quote literal encoding 
     //TODO: account for database strings that may have single \r or \n line breaks 
     // string/char 
     return "\"" + value.ToString().Replace(@"\", @"\\").Replace(Environment.NewLine, @"\n").Replace("\"", @"\""") + "\""; 
    } 
} 

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

पूरी तरह से ईमानदारी से कहूं तो, JSON स्कीमा यह संभव बनाने के द्वारा समस्या को हल करता है "उप-प्रकार" एक तारीख शाब्दिक रूप में एक स्ट्रिंग, लेकिन यह अभी भी प्रगति में काम कर रहा है और यह होगा करने के लिए किसी भी महत्वपूर्ण गोद लेने से पहले समय ले लो।

ठीक है, समय बीत चुका है। आज, ISO 8601 दिनांक प्रारूप का उपयोग करना ठीक है। मैं कोड को बदलने में परेशान नहीं हूं, 'वास्तव में कारण: यह प्राचीन है। बस JSON.Net का उपयोग करें।

+0

यदि आज से पूछा गया था, तो यह कोड समीक्षा स्टैक एक्सचेंज के बजाय होगा। मैंने इसे वहां स्थानांतरित करने के लिए ध्वजांकित किया है, लेकिन मेरे ध्यान में यह एकमात्र कारण यह है कि उसने अभी "प्रसिद्ध प्रश्न" गोल्ड बैज अर्जित किया है। यह माइग्रेशन में उस दृश्य गिनती को खोने के लिए चूसना होगा। –

+0

मुझे लगता है कि यह माइग्रेट करने के लिए बहुत पुराना होगा। यदि आप इसके ठीक हैं तो यह यहां पर रह सकता है? – Kev

+0

मुझे किसी भी तरह से कोई फर्क नहीं पड़ता, बस सर्वश्रेष्ठ फिट के बारे में सोच रहा है। मेरे पास पुरानी चीजें चली गई हैं। –

उत्तर

5

क्या यह आपके मालिकों को पुस्तकालय स्थापित करने में मदद करेगा यदि यह माइक्रोसॉफ्ट के AJAX extensions for .NET 2.0 है?

उनमें शामिल है System.Web.Script.Serialization.JavascriptSerializer, जिसका उपयोग आपकी पोस्ट में last link के चरण 4 में किया जाता है।

+0

क्या अतिरिक्त पुस्तकालयों को स्थापित किए बिना ऐसा करने का कोई तरीका है? – Steam

1

मुझे यह मिला: http://www.bramstein.com/projects/xsltjson/ आप अपने डेटाटेबल को एक्सएमएल में परिवर्तित कर सकते हैं और xml से json में कनवर्ट करने के लिए xslt स्टाइलशीट का उपयोग कर सकते हैं।

यह वास्तविक समाधान से अधिक कामकाज है।

+1

बस एक सिर ऊपर: मुझे नहीं पता कि यह कैसे कम हो गया है, लेकिन मैं अपने प्रश्नों के अच्छे विश्वासों को कम करने की आदत में नहीं हूं। –

1

हे बड्डी, यह रिक रिक ब्लॉग पोस्ट Serializing DataTable using Json.NET में है। वह विस्तार से बताता है कि James Newton King से Json.NET का उपयोग करके आप इसे कैसे पूरा कर सकते हैं।

+0

आपको लिंक्रॉट के अधीन उत्तर पोस्ट नहीं करना चाहिए –