【问题标题】:From DataTable in C# .NET to JSON从 C# .NET 中的 DataTable 到 JSON
【发布时间】:2011-01-19 18:10:16
【问题描述】:

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

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

【问题讨论】:

标签: c# .net json datatable javascriptserializer


【解决方案1】:

虽然 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);
}

【讨论】:

    【解决方案2】:

    您可以使用 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<DataTable>(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"]
    }
    

    【讨论】:

      【解决方案3】:

      您应该使用数据阅读器而不是数据表。您的代码效率低下且有些难以阅读 - 您可能想做这样的事情:

      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 :-/
      【解决方案4】:

      谢谢爱丽儿。你的回答很有帮助。 这是一个基于您的答案的版本。

      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();
      }
      

      【讨论】:

      • @user1243068 这个答案很老了。今天我可能只是将 dataReader 的内容推送到 List 并使用 JSON.NET(又名 Newtonsoft)将列表转换为 JSON 数组。
      【解决方案5】:

      谢谢卡尔文泽尔。 我遇到了一个问题,我只能从旧的 asmx 网络服务接收数据表。 现在我写了一个网页,它可以解析这个 DataTable 并以 JSON 格式返回它。

      public static string DataTableToJSON(DataTable table)
      {
          List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
      
          foreach (DataRow row in table.Rows)
          {
              Dictionary<string, object> 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);
      }
      

      【讨论】:

        【解决方案6】:

        不使用 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]", "");
                    }
        

        【讨论】:

          【解决方案7】:

          我使用 JavaScriptSerializer + LINQ

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

          【讨论】:

            猜你喜欢
            • 2019-09-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-21
            • 2011-03-20
            • 1970-01-01
            相关资源
            最近更新 更多