从C#.NET中的DataTable到JSON

我是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); } 

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

您应该使用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(); } 

然后你可以使用json.ToString获取json.ToString

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

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

 public static string DataTableToJSON(DataTable table) { var list = new List>(); foreach (DataRow row in table.Rows) { var dict = new Dictionary(); foreach (DataColumn col in table.Columns) { dict[col.ColumnName] = row[col]; } list.Add(dict); } JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(list); } 

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

 string json = JsonConvert.SerializeObject(table); 

序列化为这样的东西:

 [ { "Column1": "Row Value", "Column2": "2" } ] 

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

 string json = JsonConvert.SerializeObject(table, new Serialization.DataTableConverter()); DataTable table = JsonConvert.DeserializeObject(json, new Serialization.DataTableConverter()); 

序列化为这样的东西:

 { "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"] } 

谢谢阿里尔。 你的回答非常有帮助。 这是一个基于你的答案的版本。

 public string ReadToJson(SqlDataReader reader) { List cols = new List(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(); } 

谢谢Karl Wenzel。 我有一个问题,我只能从旧的asmx webservice接收数据表。 现在我写了一个网页,它可以解析这个DataTable并以JSON格式返回。

 public static string DataTableToJSON(DataTable table) { List> list = new List>(); foreach (DataRow row in table.Rows) { Dictionary dict = new Dictionary(); foreach (DataColumn col in table.Columns) { dict[col.ColumnName] = row[col]; } list.Add(dict); } JavaScriptSerializer serializer = new JavaScriptSerializer(); return serializer.Serialize(list); } 

不使用javascript序列化程序的另一种方法:

 public static string DataTableToJSON(DataTable Dt) { string[] StrDc = new string[Dt.Columns.Count]; string HeadStr = string.Empty; for (int i = 0; i < Dt.Columns.Count; i++) { StrDc[i] = Dt.Columns[i].Caption; HeadStr += "\"" + StrDc[i] + "\":\"" + StrDc[i] + i.ToString() + "¾" + "\","; } HeadStr = HeadStr.Substring(0, HeadStr.Length - 1); StringBuilder Sb = new StringBuilder(); Sb.Append("["); for (int i = 0; i < Dt.Rows.Count; i++) { string TempStr = HeadStr; for (int j = 0; j < Dt.Columns.Count; j++) { TempStr = TempStr.Replace(Dt.Columns[j] + j.ToString() + "¾", Dt.Rows[i][j].ToString().Trim()); } //Sb.AppendFormat("{{{0}}},",TempStr); Sb.Append("{"+TempStr + "},"); } Sb = new StringBuilder(Sb.ToString().Substring(0, Sb.ToString().Length - 1)); if(Sb.ToString().Length>0) Sb.Append("]"); return StripControlChars(Sb.ToString()); } //Function to strip control characters: //A character that does not represent a printable character but serves to initiate a particular action. public static string StripControlChars(string s) { return Regex.Replace(s, @"[^\x20-\x7F]", ""); } 

我使用JavaScriptSerializer + LINQ

 return new JavaScriptSerializer().Serialize( dataTable.Rows.Cast() .Select(row => row.Table.Columns.Cast() .ToDictionary(col => col.ColumnName, col => row[col.ColumnName])) .ToList() );