从C#.NET中的DataTable到JSON

cc0*_*cc0 14 .net c# datatable json javascriptserializer

我是C#和.NET的新手,但我已经使这段代码调用存储过程,然后我想获取返回的DataTable并将其转换为JSON.

    SqlConnection con = new SqlConnection("connection string here");
    SqlDataAdapter da = new SqlDataAdapter();
    SqlCommand cmd = new SqlCommand("getDates", con);
    SqlParameter par = new SqlParameter("@PlaceID", SqlDbType.Int);
    par.Value = 42;
    da.SelectCommand = cmd;
    cmd.Parameters.Add(par);
    DataSet ds = new DataSet();
    DataTable dt = new DataTable();

    con.Open();

    try{
        cmd.CommandType = CommandType.StoredProcedure;
        da.Fill(ds);
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,最好/最简单的方法是什么?一个例子会很棒,因为我还是很陌生.

Kar*_*zel 23

尽管JavaScriptSerializer(System.Web.Script.Serialization.JavaScriptSerializer)无法将DataTable直接转换为JSON,但可以将DataTable解压缩到可以序列化的List中.

以下函数将任意DataTable转换为JSON字符串(无需事先了解字段名称或数据类型):

public static string DataTableToJSON(DataTable table)
{
    var list = new List<Dictionary<string, object>>();

    foreach (DataRow row in table.Rows)
    {
        var dict = new Dictionary<string, object>();

        foreach (DataColumn col in table.Columns)
        {
            dict[col.ColumnName] = row[col];
        }
        list.Add(dict);
    }
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    return serializer.Serialize(list);
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ing 14

您可以使用JSON.NET库:http://json.codeplex.com/ 来序列化/反序列化DataTable.

string json = JsonConvert.SerializeObject(table);
Run Code Online (Sandbox Code Playgroud)

序列化为这样的东西:

[ { "Column1": "Row Value", "Column2": "2" } ]
Run Code Online (Sandbox Code Playgroud)

如果您需要序列化有关DataTable的更多信息,例如列模式,主键,表名,那么您可以使用我编写的自定义转换器:https://github.com/chris-herring/DataTableConverter.像这样使用它:

string json = JsonConvert.SerializeObject(table, new Serialization.DataTableConverter());
DataTable table = JsonConvert.DeserializeObject<DataTable>(json, new Serialization.DataTableConverter());
Run Code Online (Sandbox Code Playgroud)

序列化为这样的东西:

{
    "TableName": "TestTable",
    "Columns": [
        {
            "AllowDBNull": false,
            "AutoIncrement": true,
            "AutoIncrementSeed": 2,
            "AutoIncrementStep": 1,
            "Caption": "PrimaryKey",
            "ColumnName": "PrimaryKey",
            "DataType": "Int32",
            "DateTimeMode": "UnspecifiedLocal",
            "DefaultValue": null,
            "MaxLength": -1,
            "Ordinal": 0,
            "ReadOnly": false,
            "Unique": true
        }
    ],
    "Rows": [
        [
            1
        ],
        [
            2
        ],
        [
            3
        ]
    ],
    "PrimaryKey": ["PrimaryKey"]
}
Run Code Online (Sandbox Code Playgroud)


Ari*_*iel 7

您应该使用datareader而不是数据表.您的代码效率低下且难以阅读 - 您可能希望执行以下操作:

StringBuilder json = new StringBuilder();

using(SqlConnection cnn = new SqlConnection(your_connection_string)) 
{
    cnn.open();

    using(SqlCommand cmd = new SqlCommand("name_of_stored_procedure", cnn)) 
    {
        cmd.Paramters.AddWithValue("@Param", "value");

        using(SqlDataReader reader = cmd.ExecuteReader()) 
        {
            while(reader.Read()) 
            {
                json.AppendFormat("{{\"name\": \"{0}\"}}", reader["name"]);
            }
        }
    }

    cnn.close();
} 
Run Code Online (Sandbox Code Playgroud)

然后你可以json.ToString用来获得暴露


Dan*_*lph 7

谢谢Ariel.你的回答非常有帮助.这是一个基于你的答案的版本.

public string ReadToJson(SqlDataReader reader)
{
  List<string> cols = new List<string>(10);
  int ncols = reader.FieldCount;
  for (int i = 0; i < ncols; ++i)
  {
    cols.Add(reader.GetName(i));
  }
  StringBuilder sbJson = new StringBuilder("[");
  //process each row
  while (reader.Read())
  {
    sbJson.Append("{");
    foreach (string col in cols)
    {
      sbJson.AppendFormat("\"{0}\":{1}, ", col, reader[col]);
    }
    sbJson.Replace(", ", "},", sbJson.Length - 2, 2);
  }
  sbJson.Replace("},", "}]", sbJson.Length - 2, 2);
  return sbJson.ToString();
}
Run Code Online (Sandbox Code Playgroud)