plugin net mvc example asp asp.net jquery json .net-3.5 datatable

asp.net - net - DataTable a Json utilizando jquery



jquery datatable vb net (9)

Json.NET tiene la capacidad de escribir DataSets / DataTables en JSON.

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

Estoy intentando ejecutar un servicio web que devuelve una DataTable con el siguiente fragmento de código:

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

Si el servicio web devuelve una clase, funciona así que no tiene nada que ver con los parámetros de entrada, etc. Solo falla cuando el método web devuelve una tabla de datos (la tabla de datos solo tiene 2 columnas y 2 filas para la prueba que estoy haciendo).

La clase WebService está decorada con el atributo [ScriptService], así que pensé que ASP.NET serializaría automáticamente el valor de retorno como JSON. No parece funcionar con datatable.

La única solución que encontré fue devolver una cadena (un objeto serializado JSON manualmente) pero no me parece correcto hacerlo de esta forma.
Estoy usando Visual Studio 2008 con .Net 3.5


Al final, he decidido usar la clase JavaScriptSerializer para convertir DataTable en una cadena JSON. Desafortunadamente, esta clase no funciona con una DataTable, así que convertí la DataTable en una lista de dictionnaries y pasé esa lista a la clase JavaScriptSerializer. Solo requiere unas pocas líneas de código y funciona bien.
Ejemplo en 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


Al igual que Marc, tampoco me sorprende que DataTable rompa su intercambio de servicio web / json. Me gustaría respaldar a Json.NET también.

Pero si decides no seguir adelante, aún no tienes que compilar el json manualmente. Simplemente haga su propia clase personalizada con todas las propiedades que necesita y luego devuelva una matriz de esa clase. Por supuesto, tendrá que escribir un código para "convertir" su tabla de datos en su nueva clase. Lo sé, podría ser una gran cantidad de escritura de código, pero es mucho menos propenso a errores y luego tratar de hacer manualmente una cadena json.



La forma más sencilla es usar el LINQ para las extensiones de DataSet. Primero necesita crear una lista genérica (SearchSerialResults es solo una DTO en este caso) desde DataTable usando 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 es la DataTable en este caso. El paso 2 es hacer la conversión. En este caso, estoy devolviendo un objeto Json para un 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


Encontré esta clase de C # muy útil:

[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; }


Me funciona muy bien con un 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


.Net 3.5 tiene un JSONSerializer que debería poder manejar una tabla de datos. Es posible que desee revisar su código de servicio nuevamente e intentar que lo use. Además, puse un código para hacerlo manualmente en esta pregunta.


Debo admitir que no estoy muy sorprendido: DataTable básicamente rompe la mayoría de las reglas de datos estructurados. ¿Por qué no simplemente proyectar desde la tabla de datos a un objeto tipado? Una pregunta relacionada surgió antes ... o si conoce el esquema de DataTable simplemente haga la conversión en C # ...

Construir manualmente el JSON podría funcionar, pero hay muchos casos extremos que evitar; Prefiero dejar que un marco existente lo maneje, para ser honesto.