首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >DataTable到JSON

DataTable到JSON
EN

Stack Overflow用户
提问于 2009-01-16 18:28:33
回答 3查看 31.3K关注 0票数 19

我最近需要将datatable序列化为JSON。我所处的位置仍然是JSON2.0,所以我不能在.Net 3.5中使用.Net序列化程序。我想这一定是以前做过的,所以我去网上找了一下,found a number of different options。其中一些依赖于一个额外的库,我在这里很难通过它。其他人则需要首先转换为List<Dictionary<>>,这看起来有点笨拙和不必要。另一种方法将所有值都当作字符串处理。由于这样或那样的原因,我不能真正支持他们中的任何一个,所以我决定滚动我自己的,这是在下面发布的。

正如您从阅读//TODO注释中看到的那样,它在一些地方是不完整的。这段代码已经在这里生产了,所以它在基本意义上是“工作”的。它不完整的地方是我们知道我们的生产数据当前不会命中它的地方(数据库中没有时间跨度或字节数组)。我在这里发帖的原因是,我觉得这可以更好一点,我希望帮助完成和改进这段代码。欢迎任何意见。

请注意,此功能已内置于.Net 3.5及更高版本中,因此,如果您仍被限制在.Net 2.0中,那么现在使用此代码的唯一原因。即使到那时,JSON.Net也已经成为这类事情的goto库。

代码语言:javascript
复制
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("\"", @"\""") + "\"";
    }
}

更新:

这是旧的,但我想指出一些关于这段代码是如何处理日期的。我使用的格式在当时是有意义的,完全符合url的基本原理。然而,这一理由包括以下几点:

说实话,JSON Schema确实解决了这个问题,因为它可以将字符串“子类型”化为日期文字,但这项工作仍在进行中,需要一段时间才能达到任何重大的采用。

好吧,时间已经过去了。现在,只使用ISO 8601日期格式是可以的。我不会费心去修改代码,因为真的:这很古老了,就用JSON.Net吧。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-01-16 21:59:20

如果它是微软的AJAX extensions for .NET 2.0,它会帮助你说服老板安装一个库吗

其中包括System.Web.Script.Serialization.JavascriptSerializer,它在您的帖子的last link的第4步中使用。

票数 5
EN

Stack Overflow用户

发布于 2009-01-22 03:58:19

嘿,伙计,这一切都在瑞克的博客帖子Serializing DataTable using Json.NET里。他详细解释了如何使用James Newton King中的Json.NET来完成此任务。

票数 2
EN

Stack Overflow用户

发布于 2009-01-16 18:47:48

我发现: xslt您可以将数据表转换为http://www.bramstein.com/projects/xsltjson/,然后使用xslt样式表将其转换为json。

这与其说是一个真正的解决方案,不如说是一种变通方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/451460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档