DataTable для Json, используя jquery - PullRequest
5 голосов
/ 13 февраля 2009

Я пытаюсь запустить веб-сервис, который возвращает DataTable со следующим фрагментом кода:

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

Если веб-служба возвращает класс, то он работает, поэтому он не имеет ничего общего с входными параметрами и т. Д. Он не работает, только когда веб-метод возвращает таблицу данных (таблица данных имеет только 2 столбца и 2 строки для теста делает).

Класс WebService снабжен атрибутом [ScriptService], поэтому я подумал, что ASP.NET автоматически сериализует возвращаемое значение как JSON. Кажется, он не работает с датируемыми.

Единственное решение, которое я нашел, это вернуть строку (сериализованный объект JSON вручную), но мне кажется неправильным делать это таким образом.
Я использую Visual Studio 2008 с .Net 3.5

Ответы [ 9 ]

8 голосов
/ 20 февраля 2009

В конце концов, я решил использовать класс 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
5 голосов
/ 05 августа 2010

Самый простой способ - использовать расширения LINQ to DataSet. Сначала необходимо создать общий список (SearchSerialResults - это просто DTO в данном случае) из DataTable с использованием LINQ to DataSet.

            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, чтобы сделать преобразование. В этом случае я возвращаю объект Json для jqGrid.

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
4 голосов
/ 12 мая 2010
4 голосов
/ 14 февраля 2009

Json.NET имеет возможность записывать наборы данных / таблицы данных в JSON.

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

2 голосов
/ 07 сентября 2012

Это очень хорошо работает для меня с 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
1 голос
/ 13 февраля 2009

Должен признать, я не сильно удивлен - DataTable в основном нарушает большинство правил структурированных данных. Почему бы просто не проецировать из таблицы данных в типизированный объект? связанный вопрос возник раньше ... или, если вы знаете схему DataTable, просто выполните преобразование в C # ...

Сборка JSON вручную может сработать, но есть много крайних случаев, которых следует избегать; Я бы предпочел, чтобы существующий фреймворк справился с этим, если честно.

0 голосов
/ 15 июля 2012

Я нашел этот класс 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;
}
0 голосов
/ 20 февраля 2009

Как и Марк, я тоже не удивлен, что DataTable нарушает ваш обмен webservice / json. Я хотел бы также поддержать Json.NET.

Но если вы решите не делать этого, вам все равно не придется собирать JSON вручную. Просто создайте свой собственный худой пользовательский класс со всеми необходимыми свойствами и затем верните массив этого класса. Вам, конечно, придется написать код, чтобы «преобразовать» вашу таблицу данных в ваш новый класс. Я знаю, это может быть много написания кода, но это гораздо менее подвержено ошибкам, чем попытка вручную сделать строку JSON.

0 голосов
/ 13 февраля 2009

.Net 3.5 имеет JSONSerializer, который должен уметь обрабатывать данные. Возможно, вы захотите еще раз взглянуть на свой сервисный код и попытаться заставить его использовать его. Кроме того, я собрал некоторый код, чтобы сделать это вручную в этом вопросе.

...