【问题标题】:DataTable to Json using jquery使用 jquery 将数据表转换为 Json
【发布时间】:2010-10-07 11:07:05
【问题描述】:

我正在尝试执行一个 Web 服务,该服务返回一个带有以下代码的 DataTable:

$.ajax({  
    type: "POST",  
    url: url,  
    data: data,   
    contentType: "application/json; charset=utf-8",  
    dataType: "json",  
    success: function(msg) {  
        //do things  
        }  
    }); 

如果 web 服务返回一个类,那么它就可以工作,所以它与输入参数等无关。它只在 web 方法返回数据表时失败(数据表只有 2 列和 2 行用于测试我是做)。

WebService 类用 [ScriptService] 属性修饰,所以我认为 ASP.NET 会自动将返回值序列化为 JSON。它似乎不适用于数据表。

我找到的唯一解决方案是返回一个字符串(一个手动 JSON 序列化的对象),但这样做对我来说似乎不合适。
我正在使用带有 .Net 3.5 的 Visual Studio 2008

【问题讨论】:

    标签: asp.net jquery json .net-3.5 datatable


    【解决方案1】:

    最简单的方法是使用 LINQ to DataSet 扩展。首先需要使用 LINQ to DataSet 从 DataTable 创建一个通用列表(SearchSerialResults 在这种情况下只是一个 DTO)。

    var resultItems = (from DataRow dr in _returnedData.AsEnumerable() select new SearchSerialResults {
      ContractLineItem = (int) dr["fldContractLineItemID"],
        SearchItem = (string) dr["Search Item"],
        Customer = (string) dr["Customer"],
        DeviceFound = (string) dr["Device Found"],
        Country = (string) dr["Country"],
        City = (string) dr["City"],
        ContractNumber = (string) dr["Contract Number"],
        QuoteNumber = (string) dr["Quote Number"],
        BeginDate = (string) dr["Begin Date"],
        EndDate = (string) dr["End Date"]
    }).ToList();
    

    _returnedData 在这种情况下是 DataTable。第 2 步是进行转换。在这种情况下,我为 jqGrid 返回一个 Json 对象。

    var jsonObject = new {
      total = totalPages,
        pageSize,
        records = totalRecords,
        rows = (from SearchSerialResults item in resultItems select new {
          id = item.ContractLineItem,
            cell = new [] {
              item.ContractLineItem.ToString(),
                item.SearchItem,
                item.DeviceFound,
                item.Customer,
                item.ContractNumber,
                item.QuoteNumber,
                item.Country,
                item.City,
                item.BeginDate,
                item.EndDate,
                ""
            }
        }).ToArray()
    };
    return Json(jsonObject) // for MVC
    

    【讨论】:

    • 我认为你的答案是最好的。
    • 同上。使用 LINQ 并获取您需要的内容。比手动遍历结果要容易得多。
    • 很好的答案。那些让我不敢相信我不得不查一下的“duh”时刻之一。
    • 顺便说一句,您不应该使用 AsEnumerable 扩展。这很好用: var blah = (from DataRow dr in dataTable.Rows select new {prop1 = (string)dr["someString"], prop2 = (int)dr["someInt"]});
    【解决方案2】:

    WebService 非常适合我

        Imports System.Web.Script.Serialization
    
        Dim wsServicio As New ["YourWsInstance"]
        Dim dsInstEstado As New DataSet
        Dim sSql As String
    
        sSql = " Your SQL Statement"
        dsInstEstado = wsServicio.getData("YourWebServiceParameters")
        Dim jsonString = DataTableToJSON(dsInstEstado.Tables("CA_INSTITUCION"))
        Return Json(jsonString, JsonRequestBehavior.AllowGet)
    
        Function DataTableToJSon(dt As DataTable) As Object
        Dim arr(dt.Rows.Count - 1) As Object
        Dim column As DataColumn
        For i = 0 To dt.Rows.Count - 1
            Dim dict As New Dictionary(Of String, Object)
            For Each column In dt.Columns
                dict.Add(column.ColumnName, dt.Rows(i)(column))
            Next
            arr(i) = dict
        Next
       Return arr
     End Function
    

    【讨论】:

      【解决方案3】:

      我发现这个 C# 类非常有用:

      [Serializable]
      public class TableMethod
      {
          private int m_total; public int total { get { return this.m_total; } set { this.m_total = value; } }
          private int m_page; public int page { get { return this.m_page; } set { this.m_page = value; } }
          private int m_records; public int records { get { return this.m_records; } set { this.m_records = value; } }
          private IList<RowElement> m_rows; public IList<RowElement> rows { get { return this.m_rows; } set { this.m_rows = value; } }
          public TableMethod()
          {
              this.m_records = 20;
              this.m_total = 20;
              this.m_page = 1;
          }
      }
      [Serializable]
      public class RowElement
      {
          public string id;
          public string[] cell;
      }
      

      【讨论】:

      • 这里有一些解释会很有用。
      【解决方案4】:
      【解决方案5】:

      最后,我决定使用 JavaScriptSerializer 类将 DataTable 转换为 JSON 字符串。 不幸的是,此类不适用于 DataTable,因此我将 DataTable 转换为字典列表并将该列表传递给 JavaScriptSerializer 类。它只需要几行代码就可以正常工作。
      VB.net 中的示例:

          Public Function GetJson(ByVal dt As DataTable) As String
      
              Dim serializer As System.Web.Script.Serialization.JavaScriptSerializer = New System.Web.Script.Serialization.JavaScriptSerializer()
              Dim rows As New List(Of Dictionary(Of String, Object))
              Dim row As Dictionary(Of String, Object)
      
              For Each dr As DataRow In dt.Rows
                  row = New Dictionary(Of String, Object)
                  For Each col As DataColumn In dt.Columns
                      row.Add(col.ColumnName, dr(col))
                  Next
                  rows.Add(row)
              Next
              Return serializer.Serialize(rows)
          End Function
      

      【讨论】:

        【解决方案6】:

        和 Marc 一样,DataTable 破坏了您的 webservice/json 交换,我也并不感到惊讶。我也想支持 Json.NET。

        但如果您决定不使用它,您仍然不必手动构建 json。只需使用您需要的所有属性创建您自己的精益自定义类,然后返回该类的数组。当然,您必须编写代码将数据表“转换”为新类。我知道,这可能需要编写大量代码,但与尝试手动创建 json 字符串相比,它更不容易出错。

        【讨论】:

          【解决方案7】:

          【讨论】:

            【解决方案8】:

            .Net 3.5 有一个 JSONSerializer 应该能够处理数据表。您可能想再次查看您的服务代码并尝试让它使用它。另外,我把一些代码放在一起手动完成this question.

            【讨论】:

              【解决方案9】:

              我必须承认我并不感到惊讶 - DataTable 基本上违反了结构化数据的大部分规则。为什么不简单地将数据表投影到类型化对象中呢? related question 较早出现...或者如果您知道 DataTable 的架构,只需在 C# 中进行转换...

              手动构建 JSON 可能有效,但有很多边缘情况需要避免;老实说,我宁愿让现有的框架来处理它。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-04-27
                • 1970-01-01
                • 2017-12-01
                • 1970-01-01
                • 2019-05-01
                • 2017-01-13
                • 1970-01-01
                • 2017-01-24
                相关资源
                最近更新 更多