在 C# 中将数据表转换为 JSON

Posted

技术标签:

【中文标题】在 C# 中将数据表转换为 JSON【英文标题】:Convert datatable to JSON in C# 【发布时间】:2013-06-28 04:38:25 【问题描述】:
    我想从数据库中获取记录到DataTable。 然后将DataTable 转换为JSON 对象。 将 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

] 

我该怎么做?

【问题讨论】:

DataTable to JSON的可能重复 【参考方案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;
        

    

【讨论】:

以上是关于在 C# 中将数据表转换为 JSON的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中将 JSON 数组转换为 XML

在C#中将对象转换为JSON字符串[重复]

YamlDotNet 在 C# 中将 YAML 转换为 JSON

在c#中将html转换为json

在c#中将简单的json转换为字符串数组

在 C# 中将字符串转换为 json 格式。 Newtonsoft.json 显示黄色标记