6

次のコードで DataTable を返す Web サービスを実行しようとしています。

$.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

この 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 に答える
0

Marc のように、私も DataTable が webservice/json 交換を壊すことに驚きません。Json.NET も支持したいと思います。

ただし、それを使用しないことにした場合でも、json を手動でビルドする必要はありません。必要なすべてのプロパティを備えた独自の無駄のないカスタム クラスを作成し、そのクラスの配列を返すだけです。もちろん、データ テーブルを新しいクラスに「変換」するコードを記述する必要があります。多くのコードを書く必要があることはわかっていますが、json文字列を手動で作成しようとするよりもエラーが発生しにくくなります。

于 2009-02-20T07:07:41.073 に答える
0

.Net 3.5 には、データテーブルを処理できるはずの JSONSerializer があります。サービスコードをもう一度見て、それを使用できるようにしてみてください。また、この質問で手動で行うためにいくつかのコードをまとめました。

于 2009-02-13T14:43:42.763 に答える