【问题标题】:Convert datatable to JSON in C#在 C# 中将数据表转换为 JSON
【发布时间】:2013-06-28 04:38:25
【问题描述】:
  1. 我想从数据库中获取记录到DataTable
  2. 然后将DataTable 转换为JSON 对象。
  3. 将 JSON 对象返回给我的 JavaScript 函数。

我通过调用使用this代码:

string result = JsonConvert.SerializeObject(DatatableToDictionary(queryResult, "Title"), Newtonsoft.Json.Formatting.Indented);

要将 DataTable 转换为 JSON,它可以正常工作并返回以下内容:

{
    "1": {
    "viewCount": 703,
    "clickCount": 98
    },
    "2": {
    "viewCount": 509,
    "clickCount": 85
    },
    "3": {
    "viewCount": 578,
    "clickCount": 86
    },
    "4": {
    "viewCount": 737,
    "clickCount": 108
    },
    "5": {
    "viewCount": 769,
    "clickCount": 130
    }
} 

但我希望它返回以下内容:

{"records":[
{
"Title": 1,
"viewCount": 703,
"clickCount": 98
},
{
"Title": 2,
"viewCount": 509,
"clickCount": 85
},
{
"Title": 3,
"viewCount": 578,
"clickCount": 86
},
{
"Title": 4,
"viewCount": 737,
"clickCount": 108
},
{
"Title": 5,
"viewCount": 769,
"clickCount": 130
}
]} 

我该怎么做?

【问题讨论】:

标签: c# json datatable


【解决方案1】:

Convert Datatable to JSON String in C#, VB.NET 的这段代码 sn-p 可能会对您有所帮助。 它使用System.Web.Script.Serialization.JavaScriptSerializer将内容序列化为JSON格式:

public string ConvertDataTabletoString()
{
    DataTable dt = new DataTable();
    using (SqlConnection con = new SqlConnection("Data Source=SureshDasari;Initial Catalog=master;Integrated Security=true"))
    {
        using (SqlCommand cmd = new SqlCommand("select title=City,lat=latitude,lng=longitude,description from LocationDetails", con))
        {
            con.Open();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
            Dictionary<string, object> row;
            foreach (DataRow dr in dt.Rows)
            {
                row = new Dictionary<string, object>();
                foreach (DataColumn col in dt.Columns)
                {
                    row.Add(col.ColumnName, dr[col]);
                }
                rows.Add(row);
            }
            return serializer.Serialize(rows);
        }
    }
}

【讨论】:

  • 如果我有 2 个数据表,我需要将它们转换为一个 json 字符串,但我需要 json 数组中的每个数据表,我该怎么办?
  • @如何将此数据添加到表中
  • 可以使用Json.Net代替JavaScriptSerializer:return Newtonsoft.Json.JsonConvert.SerializeObject(rows);
  • 对我来说(.NET Framework 4.5),System.Web.Script 中的“脚本”无法识别/解析; “seralizer.Serialize(rows)”中的“Serialize”也不是
【解决方案2】:

要在 Json 方法中访问转换数据表的值,请按照以下步骤操作:

$.ajax({
        type: "POST",
        url: "/Services.asmx/YourMethodName",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            var parsed = $.parseJSON(data.d);
            $.each(parsed, function (i, jsondata) {
            $("#dividtodisplay").append("Title: " + jsondata.title + "<br/>" + "Latitude: " + jsondata.lat);
            });
        },
        error: function (XHR, errStatus, errorThrown) {
            var err = JSON.parse(XHR.responseText);
            errorMessage = err.Message;
            alert(errorMessage);
        }
    });

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 我可以知道为什么我被否决了吗?它是一个工作代码-sn-p ...它正在生产环境中使用。
    • 可能是因为您在可能使用更多面向对象的方法时手动创建 JSON 结构。这样做很麻烦。
    • @JoshM。 - 我的回答是为了展示另一种给猫鼬剥皮的方法。
    • 某件事告诉我,程序员应该能够像使用 3rd 方工具一样编写代码,而且对于这么简单的事情,编写自定义代码可能比使用臃肿的工具更好。
    【解决方案4】:

    您可以使用与 Alireza Maddah 指定的相同方式,如果您想将两个数据表用于一个 json 数组,请使用以下方式:

    public string ConvertDataTabletoString()
    {
    DataTable dt = new DataTable();
    DataTable dt1 = new DataTable();
    using (SqlConnection con = new SqlConnection("Data Source=SureshDasari;Initial Catalog=master;Integrated Security=true"))
    {
        using (SqlCommand cmd = new SqlCommand("select title=City,lat=latitude,lng=longitude,description from LocationDetails", con))
        {
            con.Open();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            da.Fill(dt);
            System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
            Dictionary<string, object> row;
            foreach (DataRow dr in dt.Rows)
            {
                row = new Dictionary<string, object>();
                foreach (DataColumn col in dt.Columns)
                {
                    row.Add(col.ColumnName, dr[col]);
                }
                rows.Add(row);
            }
            SqlCommand cmd1 = new SqlCommand("_another_query_", con);
                    SqlDataAdapter da1 = new SqlDataAdapter(cmd1);
                    da1.Fill(dt1);
                    System.Web.Script.Serialization.JavaScriptSerializer serializer1 = new System.Web.Script.Serialization.JavaScriptSerializer();
                    Dictionary<string, object> row1;
                    foreach (DataRow dr in dt1.Rows) //use the old variable rows only
                    {
                        row1 = new Dictionary<string, object>();
                        foreach (DataColumn col in dt1.Columns)
                        {
                            row1.Add(col.ColumnName, dr[col]);
                        }
                        rows.Add(row1); // Finally You can add into old json array in this way
                    }
            return serializer.Serialize(rows);
        }
    }
    }
    

    同样的方法可以用于任意数量的数据表。

    【讨论】:

      【解决方案5】:

      我们可以通过两种简单的方式完成任务,一种是使用 Json.NET dll,另一种是使用 StringBuilder 类。

      使用 Newtonsoft Json.NET

      string JSONresult;
      JSONresult = JsonConvert.SerializeObject(dt);  
      Response.Write(JSONresult);
      

      参考链接:Newtonsoft: Convert DataTable to JSON object in ASP.Net C#

      使用 StringBuilder

      public string DataTableToJsonObj(DataTable dt)
      {
          DataSet ds = new DataSet();
          ds.Merge(dt);
          StringBuilder JsonString = new StringBuilder();
          if (ds != null && ds.Tables[0].Rows.Count > 0)
          {
              JsonString.Append("[");
              for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
              {
                  JsonString.Append("{");
                  for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
                  {
                      if (j < ds.Tables[0].Columns.Count - 1)
                      {
                          JsonString.Append("\"" + ds.Tables[0].Columns[j].ColumnName.ToString() + "\":" + "\"" + ds.Tables[0].Rows[i][j].ToString() + "\",");
                      }
                      else if (j == ds.Tables[0].Columns.Count - 1)
                      {
                          JsonString.Append("\"" + ds.Tables[0].Columns[j].ColumnName.ToString() + "\":" + "\"" + ds.Tables[0].Rows[i][j].ToString() + "\"");
                      }
                  }
                  if (i == ds.Tables[0].Rows.Count - 1)
                  {
                      JsonString.Append("}");
                  }
                  else
                  {
                      JsonString.Append("},");
                  }
              }
              JsonString.Append("]");
              return JsonString.ToString();
          }
          else
          {
              return null;
          }
      }
      

      【讨论】:

      • 这个功能很好,但是如何处理DataTable行字段中的双引号。
      • 由于某种原因,JsonString 方法的速度大约是 SerializeObject 的两倍......在大型数据集上性能也不是很好。
      • 这段代码不错,但是直接从数据表参数读取数据会快很多,而不是创建另一个变量
      • 这不是一个很好的解决方案。对于初学者,如果您的数据库中有任何包含引号字符的值 - 这将失败。你最好使用 Newtonsoft 包中的 JsonTextWriter
      • 使用使用 Newtonsoft Json.NET 可能是 IMO 最简单和最好的解决方案
      【解决方案6】:

      使用 C#.net 将数据表转换为 JSON

       public static object 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] = (Convert.ToString(row[col]));
                  }
                  list.Add(dict);
              }
              JavaScriptSerializer serializer = new JavaScriptSerializer();
      
              return serializer.Serialize(list);
          }
      

      【讨论】:

        【解决方案7】:

        这与接受的答案有类似的方法,但使用 LINQ 将数据表转换为单行代码中的列表。

        //convert datatable to list using LINQ. Input datatable is "dt", returning list of "name:value" tuples
        var lst = dt.AsEnumerable()
            .Select(r => r.Table.Columns.Cast<DataColumn>()
                    .Select(c => new KeyValuePair<string, object>(c.ColumnName, r[c.Ordinal])
                   ).ToDictionary(z=>z.Key,z=>z.Value)
            ).ToList();
        //now serialize it
        var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        return serializer.Serialize(lst);
        

        这是一种非常有用的枚举数据表的方法,这通常需要大量的编码!以下是一些变化:

        //convert to list with array of values for each row
        var list1 = dt.AsEnumerable().Select(r => r.ItemArray.ToList()).ToList();
        
        //convert to list of first column values only
        var list2 = dt.AsEnumerable().Select(r => r.ItemArray[0]).ToList();
        
        // parse a datatable with conditions and get CSV string
        string MalesOver21 = string.Join(",",
            dt.AsEnumerable()
              .Where(r => r["GENDER"].ToString()=="M" && r.Field<int>("AGE")>21)
              .Select(r => r.Field<string>("FULLNAME"))
         );
        

        这与原始问题无关,但为了完整起见,我想提一下,如果您只想从现有数据表中过滤掉行,See this answer

        【讨论】:

        • 假设我使用了这段代码,我会在 View 上放什么来显示 json 数据?
        • 这是一个非常开放的问题。您可以使用许多 JavaScript 框架和工具来解析发送到视图的数据。以 JQgrid 为例。或者您可以使用 JavaScript 使用 For 循环解析列表,并使用 html 手动构造一个表。在我的最后一个示例malesover21 中,我将结果连接成一个字符串。您可以在 C# 中构建一个 html 表格或列表,然后返回内容。
        • 好的,谢谢。我最终使用 jquery 自动完成小部件来显示列表。您的代码帮助很大,谢谢! :)
        【解决方案8】:

        试试这个自定义函数。

            public static string DataTableToJsonObj(DataTable dt)
            {
                DataSet ds = new DataSet();
                ds.Merge(dt);
                StringBuilder jsonString = new StringBuilder();
        
                if (ds.Tables[0].Rows.Count > 0)
                {
                    jsonString.Append("[");
                    for (int rows = 0; rows < ds.Tables[0].Rows.Count; rows++)
                    {
                        jsonString.Append("{");
                        for (int cols = 0; cols < ds.Tables[0].Columns.Count; cols++)
                        {
                            jsonString.Append(@"""" + ds.Tables[0].Columns[cols].ColumnName + @""":");
        
                            /* 
                            //IF NOT LAST PROPERTY
        
                            if (cols < ds.Tables[0].Columns.Count - 1)
                            {
                                GenerateJsonProperty(ds, rows, cols, jsonString);
                            }
        
                            //IF LAST PROPERTY
        
                            else if (cols == ds.Tables[0].Columns.Count - 1)
                            {
                                GenerateJsonProperty(ds, rows, cols, jsonString, true);
                            }
                            */
        
                            var b = (cols < ds.Tables[0].Columns.Count - 1)
                                ? GenerateJsonProperty(ds, rows, cols, jsonString)
                                : (cols != ds.Tables[0].Columns.Count - 1)
                                  || GenerateJsonProperty(ds, rows, cols, jsonString, true);
                        }
                        jsonString.Append(rows == ds.Tables[0].Rows.Count - 1 ? "}" : "},");
                    }
                    jsonString.Append("]");
                    return jsonString.ToString();
                }
                return null;
            }
        
            private static bool GenerateJsonProperty(DataSet ds, int rows, int cols, StringBuilder jsonString, bool isLast = false)
            {
        
                // IF LAST PROPERTY THEN REMOVE 'COMMA'  IF NOT LAST PROPERTY THEN ADD 'COMMA'
                string addComma = isLast ? "" : ",";
        
                if (ds.Tables[0].Rows[rows][cols] == DBNull.Value)
                {
                    jsonString.Append(" null " + addComma);
                }
                else if (ds.Tables[0].Columns[cols].DataType == typeof(DateTime))
                {
                    jsonString.Append(@"""" + (((DateTime)ds.Tables[0].Rows[rows][cols]).ToString("yyyy-MM-dd HH':'mm':'ss")) + @"""" + addComma);
                }
                else if (ds.Tables[0].Columns[cols].DataType == typeof(string))
                {
                    jsonString.Append(@"""" + (ds.Tables[0].Rows[rows][cols]) + @"""" + addComma);
                }
                else if (ds.Tables[0].Columns[cols].DataType == typeof(bool))
                {
                    jsonString.Append(Convert.ToBoolean(ds.Tables[0].Rows[rows][cols]) ? "true" : "fasle");
                }
                else
                {
                    jsonString.Append(ds.Tables[0].Rows[rows][cols] + addComma);
                }
        
                return true;
            }
        

        【讨论】:

        • 在此之后像这样反序列化您的数组。 var deserializeArray = new JavaScriptSerializer().Deserialize(desrilizeDashboard);
        【解决方案9】:
        public static string ConvertIntoJson(DataTable dt)
        {
            var jsonString = new StringBuilder();
            if (dt.Rows.Count > 0)
            {
                jsonString.Append("[");
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    jsonString.Append("{");
                    for (int j = 0; j < dt.Columns.Count; j++)
                        jsonString.Append("\"" + dt.Columns[j].ColumnName + "\":\"" 
                            + dt.Rows[i][j].ToString().Replace('"','\"') + (j < dt.Columns.Count - 1 ? "\"," : "\""));
        
                    jsonString.Append(i < dt.Rows.Count - 1 ? "}," : "}");
                }
                return jsonString.Append("]").ToString();
            }
            else
            {
                return "[]";
            }
        }
        public static string ConvertIntoJson(DataSet ds)
        {
            var jsonString = new StringBuilder();
            jsonString.Append("{");
            for (int i = 0; i < ds.Tables.Count; i++)
            {
                jsonString.Append("\"" + ds.Tables[i].TableName + "\":");
                jsonString.Append(ConvertIntoJson(ds.Tables[i]));
                if (i < ds.Tables.Count - 1)
                    jsonString.Append(",");
            }
            jsonString.Append("}");
            return jsonString.ToString();
        }
        

        【讨论】:

          【解决方案10】:
          //Common DLL client, server
          public class transferDataTable
          {
              public class myError
              {
                  public string Message { get; set; }
                  public int Code { get; set; }
              }
          
              public myError Error { get; set; }
              public List<string> ColumnNames { get; set; }
              public List<string> DataTypes { get; set; }
              public List<Object> Data { get; set; }
              public int Count { get; set; }
          }
          
          public static class ExtensionMethod
          {
              public static transferDataTable LoadData(this transferDataTable transfer, DataTable dt)
              {
                  if (dt != null)
                  {
                      transfer.DataTypes = new List<string>();
                      transfer.ColumnNames = new List<string>();                
                      foreach (DataColumn c in dt.Columns)
                      {
                          transfer.ColumnNames.Add(c.ColumnName);
                          transfer.DataTypes.Add(c.DataType.ToString());
                      }
          
                      transfer.Data = new List<object>();
                      foreach (DataRow dr in dt.Rows)
                      {
                          foreach (DataColumn col in dt.Columns)
                          {
                              transfer.Data.Add(dr[col] == DBNull.Value ? null : dr[col]);
                          }
                      }
                      transfer.Count = dt.Rows.Count;
                  }            
                  return transfer;
              }        
          
              public static DataTable GetDataTable(this transferDataTable transfer, bool ConvertToLocalTime = true)
              {
                  if (transfer.Error != null || transfer.ColumnNames == null || transfer.DataTypes == null || transfer.Data == null)
                      return null;
          
                  int columnsCount = transfer.ColumnNames.Count;
                  DataTable dt = new DataTable();
                  for (int i = 0; i < columnsCount; i++ )
                  {
                      Type colType = Type.GetType(transfer.DataTypes[i]);
                      dt.Columns.Add(new DataColumn(transfer.ColumnNames[i], colType));
                  }
          
                  int index = 0;
                  DataRow row = dt.NewRow();
                  foreach (object o in transfer.Data)
                  {
                      if (ConvertToLocalTime && o != null && o.GetType() == typeof(DateTime))
                      {
                          DateTime dat = Convert.ToDateTime(o);
                          row[index] = dat.ToLocalTime();
                      }
                      else
                          row[index] = o == null ? DBNull.Value : o;
          
                      index++;
          
                      if (columnsCount == index)
                      {
                          index = 0;
                          dt.Rows.Add(row);
                          row = dt.NewRow();
                      }
                  }
                  return dt;
              }
          }
          
          //Server
              [OperationContract]
              [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest, UriTemplate = "json/data")]
              transferDataTable _Data();
          
              public transferDataTable _Data()
              {
                  try
                  {
                      using (SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["myConnString"]))
                      {
                          con.Open();
                          DataSet ds = new DataSet();
                          SqlDataAdapter myAdapter = new SqlDataAdapter("SELECT * FROM tbGalleries", con);
                          myAdapter.Fill(ds, "table");
                          DataTable dt = ds.Tables["table"];
                          return new transferDataTable().LoadData(dt);
                      }
                  }
                  catch(Exception ex)
                  {
                      return new transferDataTable() { Error = new transferDataTable.myError() { Message = ex.Message, Code = ex.HResult } };
                  }
              }
          
          //Client
                  Response = Vossa.getAPI(serviceUrl + "json/data");
                  transferDataTable transfer = new JavaScriptSerializer().Deserialize<transferDataTable>(Response);
                  if (transfer.Error == null)
                  {
                      DataTable dt = transfer.GetDataTable();
                      dbGrid.ItemsSource = dt.DefaultView;
                  }
                  else
                      MessageBox.Show(transfer.Error.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
          

          【讨论】:

          • 如果您需要通过 WebService API 发送通用 SQL 请求,您可以使用我的解决方案。
          • 如果您需要通过 WebService API 发送通用 SQL 请求,您可以使用我的解决方案。类 transferDataTable 是可串行化的对象。该对象将在客户端和服务器之间发送。方法 LoadData(在服务器上)用 DataTable 填充对象 transferDataTable。值 DBNull.Value 不能通过 web.api 传输,然后我用 null 替换了这个值)。在对客户端空值进行反序列化后,将由 DBNull.Value 替换。客户端上的GetDataTable方法恢复了rest api发送的DataTable。如果出现错误,则客户端显示消息。
          • 请编辑您的答案并在此处添加说明
          【解决方案11】:

          我有简单的函数将数据表转换为 json 字符串。

          我使用 Newtonsoft 来生成字符串。我不使用 Newtonsoft 来完全序列化 Datatable。小心这个。

          也许这会很有用。

           private string DataTableToJson(DataTable dt) {
            if (dt == null) {
             return "[]";
            };
            if (dt.Rows.Count < 1) {
             return "[]";
            };
          
            JArray array = new JArray();
            foreach(DataRow dr in dt.Rows) {
             JObject item = new JObject();
             foreach(DataColumn col in dt.Columns) {
              item.Add(col.ColumnName, dr[col.ColumnName]?.ToString());
             }
             array.Add(item);
            }
          
            return array.ToString(Newtonsoft.Json.Formatting.Indented);
           }
          

          【讨论】:

          • 我已经在使用这个代码了。你得到什么类型的错误?
          • 你不能使用那个确切的代码,因为它不能编译!
          • 你确定你有重要的正确命名空间吗? gist.github.com/ecdundar/df123aa2526b72cd8df976423ead8daf
          • 提示:item.Add(col.ColumnName, dr[col.ColumnName] ? .ToString());
          【解决方案12】:

          将数据传递给此方法,它将返回 json 字符串。

          public DataTable GetTable()
                  {
                      string str = "Select * from GL_V";
                      OracleCommand cmd = new OracleCommand(str, con);
                      cmd.CommandType = CommandType.Text;
                      DataTable Dt = OracleHelper.GetDataSet(con, cmd).Tables[0];
          
                      return Dt;
                  }
          
                  public string DataTableToJSONWithJSONNet(DataTable table)
                  {
                      string JSONString = string.Empty;
                      JSONString = JsonConvert.SerializeObject(table);
                      return JSONString;
                  }
          
          
          
          public static DataSet GetDataSet(OracleConnection con, OracleCommand cmd)
                  {
                      // create the data set  
                      DataSet ds = new DataSet();
                      try
                      {
                          //checking current connection state is open
                          if (con.State != ConnectionState.Open)
                              con.Open();
          
                          // create a data adapter to use with the data set
                          OracleDataAdapter da = new OracleDataAdapter(cmd);
          
                          // fill the data set
                          da.Fill(ds);
                      }
                      catch (Exception ex)
                      {
          
                          throw;
                      }
                      return ds;
                  }
          

          【讨论】:

            【解决方案13】:

            使用Cinchoo ETL - 一个开源库,您可以通过几行代码轻松地将 DataTable 导出为 JSON

            StringBuilder sb = new StringBuilder();
            string connectionstring = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwind;Integrated Security=True";
            using (var conn = new SqlConnection(connectionstring))
            {
                conn.Open();
                var comm = new SqlCommand("SELECT * FROM Customers", conn);
                SqlDataAdapter adap = new SqlDataAdapter(comm);
            
                DataTable dt = new DataTable("Customer");
                adap.Fill(dt);
            
                using (var parser = new ChoJSONWriter(sb))
                    parser.Write(dt);
            }
            
            Console.WriteLine(sb.ToString());
            

            输出:

            {
              "Customer": [
                {
                  "CustomerID": "ALFKI",
                  "CompanyName": "Alfreds Futterkiste",
                  "ContactName": "Maria Anders",
                  "ContactTitle": "Sales Representative",
                  "Address": "Obere Str. 57",
                  "City": "Berlin",
                  "Region": null,
                  "PostalCode": "12209",
                  "Country": "Germany",
                  "Phone": "030-0074321",
                  "Fax": "030-0076545"
                },
                {
                  "CustomerID": "ANATR",
                  "CompanyName": "Ana Trujillo Emparedados y helados",
                  "ContactName": "Ana Trujillo",
                  "ContactTitle": "Owner",
                  "Address": "Avda. de la Constitución 2222",
                  "City": "México D.F.",
                  "Region": null,
                  "PostalCode": "05021",
                  "Country": "Mexico",
                  "Phone": "(5) 555-4729",
                  "Fax": "(5) 555-3745"
                }
              ]
            }
            

            【讨论】:

              【解决方案14】:

              试试这个(扩展方法):

              public static string ToJson(this DataTable dt)
              {
                  List<Dictionary<string, object>> lst = new List<Dictionary<string, object>>();
                  Dictionary<string, object> item;
                  foreach (DataRow row in dt.Rows)
                  {
                          item = new Dictionary<string, object>();
                              foreach (DataColumn col in dt.Columns)
                              {
                                  item.Add(col.ColumnName, (Convert.IsDBNull(row[col]) ? null : row[col]));       
                      }
                      lst.Add(item);
                  }
                      return Newtonsoft.Json.JsonConvert.SerializeObject(lst);
              }
              

              并使用:

              DataTable dt = new DataTable();
              .
              .
              .
              var json = dt.ToJson();
              

              【讨论】:

                【解决方案15】:

                我正在使用这个函数来描述表格。
                填完数据表后使用

                static public string DataTableToJSON(DataTable dataTable,bool readableformat=true)
                        {
                            string JSONString="[";
                            string JSONRow;
                            string colVal;
                            foreach(DataRow dataRow in dataTable.Rows)
                            {
                                if(JSONString!="[") { JSONString += ","; }
                                JSONRow = "";
                                if (readableformat) { JSONRow += "\r\n"; }
                                JSONRow += "{";
                
                                foreach (DataColumn col in dataTable.Columns)
                                {
                                    colVal = dataRow[col].ToString();
                                    colVal = colVal.Replace("\"", "\\\"");
                                    colVal = colVal.Replace("'", "\\\'");
                                    if(JSONRow!="{"&&JSONRow!="\r\n{") {
                
                                        JSONRow += ",";
                
                                    }
                                    JSONRow += "\"" + col.ColumnName + "\":\"" + colVal + "\"";
                
                                }
                                JSONRow += "}";
                                JSONString += JSONRow;
                            }
                            JSONString += "\r\n]";
                            return JSONString;
                        }
                

                MySQL 查询:“DESCRIBE 表名;”; DataTableToJSON(dataTable) 示例输出:

                [
                {"Field":"id","Type":"int(5)","Null":"NO","Key":"PRI","Default":"","Extra":"auto_increment"},
                {"Field":"ad","Type":"int(11) unsigned","Null":"NO","Key":"MUL","Default":"","Extra":""},
                {"Field":"soyad","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""},
                {"Field":"ulke","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""},
                {"Field":"alan","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""},
                {"Field":"numara","Type":"varchar(20)","Null":"NO","Key":"","Default":"","Extra":""}
                ]
                

                用 PHP 测试:

                $X='[
                {"Field":"id","Type":"int(5)","Null":"NO","Key":"PRI","Default":"","Extra":"auto_increment"},
                {"Field":"ad","Type":"int(11) unsigned","Null":"NO","Key":"MUL","Default":"","Extra":""},
                {"Field":"soyad","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""},
                {"Field":"ulke","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""},
                {"Field":"alan","Type":"varchar(20)","Null":"YES","Key":"","Default":"","Extra":""},
                {"Field":"numara","Type":"varchar(20)","Null":"NO","Key":"","Default":"","Extra":""}
                ]';
                $Y=json_decode($X,true);
                echo $Y[0]["Field"];
                var_dump($Y);
                

                【讨论】:

                  【解决方案16】:

                  现在非常简单..

                  string json = JsonConvert.SerializeObject(YourDataTable, Formatting.Indented);
                  

                  现在将您的 Json 转换为 DataTable:

                  YourDataTable = (DataTable)JsonConvert.DeserializeObject(json, (typeof(DataTable)));
                  

                  也适用于数据集..

                  【讨论】:

                    【解决方案17】:

                    所有这些答案都非常适合移动数据!他们失败的地方是保留要移动的数据的列类型。当您想要执行诸如合并看起来相同的数据表之类的事情时,这会成为一个问题。 JsonConvert 会查看第一行数据来确定列数据类型,可能猜测错误。

                    解决这个问题;

                    • 在单独的响应对象中序列化 DataTableDataColumn 定义。
                    • 在读入表格之前反序列化响应中的DataColumn 定义。
                    • 反序列化并合并 DataTable,忽略 Json 定义的架构。

                    听起来很多,但它只增加了三行代码。

                    // Get our Column definitions and serialize them using an anoymous function.
                    var columns = dt.Columns.Cast<DataColumn>().Select(c => new { DataPropertyName = c.ColumnName, DataPropertyType = c.DataType.ToString()});
                    resp.ObjSchema = JsonConvert.SerializeObject(columns);
                    resp.Obj = JsonConvert.SerializeObject(dt);
                    

                    resp.ObjSchema 变为;

                    [
                      {
                        "DataPropertyName": "RowId",
                        "DataPropertyType ": "System.Int32"
                      },
                      {
                        "DataPropertyName": "ItemName",
                        "DataPropertyType ": "System.String"
                      }
                    ]
                    

                    我们可以在 resp.ObjSchema 上使用 LINQ 来自己定义它们,而不是让 Json 通过 dt = JsonConvert.DeserializeObject&lt;DataTable&gt;(response) 定义列定义。我们将使用MissingSchemaAction.Ignore 来忽略 Json 提供的架构。

                    // If your environment does not support dynamic you'll need to create a class for with DataPropertyName and DataPropertyType.
                    JsonConvert.DeserializeObject<List<dynamic>>(response.ObjSchema).ForEach(prop =>
                    {
                        dt.Columns.Add(new DataColumn() { ColumnName = prop.DataPropertyName, DataType = Type.GetType(prop.DataPropertyType.ToString()) });
                    });
                    // Merge the results ignoring the JSON schema.
                    dt.Merge(JsonConvert.DeserializeObject<DataTable>(response.Obj), true, MissingSchemaAction.Ignore);
                    

                    【讨论】:

                    • 谢谢。我创建了一个基于您的答案的答案。我只是将它全部封装在一个类中。使其更容易,并允许其他人简单地复制、粘贴和使用。
                    【解决方案18】:

                    基于 clamchoda 的 答案(保留数据类型),我为此创建了一个类,可以像下面这样使用:

                    DataTable 转换为Json

                    JsonDataTable j = JsonDataTable.FromDataTable(myDataTable);

                    Json 转换回DataTable

                    DataTable myDataTable = j.ToDataTable();

                    public class JsonDataTable
                        {
                            public string Schema { get; set; }
                            public string Table { get; set; }
                    
                            public static JsonDataTable FromDataTable(DataTable dt)
                            {
                                JsonDataTable j = new JsonDataTable();
                                var columns = dt.Columns.Cast<DataColumn>().Select(c => new { DataPropertyName = c.ColumnName, DataPropertyType = c.DataType.ToString() });
                                j.Schema = JsonConvert.SerializeObject(columns);
                                j.Table = JsonConvert.SerializeObject(dt);
                                return j;
                            }
                    
                    
                            public DataTable ToDataTable()
                            {
                                DataTable dt = new DataTable();
                    
                                JsonConvert.DeserializeObject<List<dynamic>>(Schema).ForEach(prop =>
                                {
                                    dt.Columns.Add(new DataColumn() { ColumnName = prop.DataPropertyName, DataType = Type.GetType(prop.DataPropertyType.ToString()) });
                                });
                    
                                dt.Merge(JsonConvert.DeserializeObject<DataTable>(Table), true, MissingSchemaAction.Ignore);
                    
                                return dt;
                            }
                    
                        }
                    
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2021-05-19
                      • 1970-01-01
                      • 1970-01-01
                      • 2017-01-24
                      • 2012-08-12
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多