पर डेटाटेबल मुझे हाल ही में जेएसओएन के लिए एक डाटाटेबल को क्रमबद्ध करने की आवश्यकता है। जहां मैं हूं, हम अभी भी .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 का उपयोग करें।
यदि आज से पूछा गया था, तो यह कोड समीक्षा स्टैक एक्सचेंज के बजाय होगा। मैंने इसे वहां स्थानांतरित करने के लिए ध्वजांकित किया है, लेकिन मेरे ध्यान में यह एकमात्र कारण यह है कि उसने अभी "प्रसिद्ध प्रश्न" गोल्ड बैज अर्जित किया है। यह माइग्रेशन में उस दृश्य गिनती को खोने के लिए चूसना होगा। –
मुझे लगता है कि यह माइग्रेट करने के लिए बहुत पुराना होगा। यदि आप इसके ठीक हैं तो यह यहां पर रह सकता है? – Kev
मुझे किसी भी तरह से कोई फर्क नहीं पड़ता, बस सर्वश्रेष्ठ फिट के बारे में सोच रहा है। मेरे पास पुरानी चीजें चली गई हैं। –