6

我正在尝试执行一个 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

4

9 回答 9

8

最后,我决定使用 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
于 2009-02-20T10:55:15.707 回答
6

最简单的方法是使用 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
于 2010-08-05T17:07:21.467 回答
4

Json.NET 能够将 DataSets/DataTables 写入 JSON。

http://james.newtonking.com/archive/2008/09/06/dataset-datatable-serialization-with-json-net.aspx

于 2009-02-13T23:43:50.327 回答
4

http://schotime.net/blog/index.php/2008/07/27/dataset-datatable-to-json/

于 2010-05-12T16:24:56.210 回答
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
于 2012-09-07T18:48:44.817 回答
1

我必须承认我并不感到惊讶——DataTable基本上打破了结构化数据的大部分规则。为什么不简单地将数据表投影到类型化对象中呢?之前出现了一个相关问题......或者如果您知道DataTable在 C# 中进行转换的架构......

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

于 2009-02-13T14:38:10.217 回答
0

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

于 2009-02-13T14:43:42.763 回答
0

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

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

于 2009-02-20T07:07:41.073 回答
0

我发现这个 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;
}
于 2012-07-15T03:02:15.103 回答