Обработка данных на стороне сервера jQuery DataTables и ASP.Net
Я пытаюсь использовать функциональные возможности сервера плагина jQuery Datatables с ASP.Net. Запрос ajax возвращает действительный JSON, но ничего не отображается в таблице.
У меня изначально возникли проблемы с данными, которые я отправлял в запросе ajax. Я получил ошибку "Недействительный JSON-примитив". Я обнаружил, что данные должны быть в строке вместо сериализации JSON, как описано в этом сообщении: http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/. Я не был уверен, как это исправить, поэтому я попытался добавить это в запрос ajax:
"data": "{'sEcho': '" + aoData.sEcho + "'}"
Если в конечном итоге будет работать, я добавлю другие параметры позже. Прямо сейчас я просто пытаюсь найти что-то, что появится в моем столе.
Возвращающийся JSON выглядит нормально и проверяет, но sEcho в сообщении undefined, и я думаю, что поэтому данные не загружаются в таблицу.
Итак, что я делаю неправильно? Я даже на правильном пути, или я глуп? Кто-нибудь сталкивался с этим раньше или имел какие-либо предложения?
Здесь мой jQuery:
$(document).ready(function()
{
$("#grid").dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"bServerSide":true,
"sAjaxSource": "GridTest.asmx/ServerSideTest",
"fnServerData": function(sSource, aoData, fnCallback) {
$.ajax({
"type": "POST",
"dataType": 'json',
"contentType": "application/json; charset=utf-8",
"url": sSource,
"data": "{'sEcho': '" + aoData.sEcho + "'}",
"success": fnCallback
});
}
});
});
HTML:
<table id="grid">
<thead>
<tr>
<th>Last Name</th>
<th>First Name</th>
<th>UserID</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5" class="dataTables_empty">Loading data from server</td>
</tr>
</tbody>
</table>
WebMethod:
<WebMethod()> _
Public Function ServerSideTest() As Data
Dim list As New List(Of String)
list.Add("testing")
list.Add("chad")
list.Add("testing")
Dim container As New List(Of List(Of String))
container.Add(list)
list = New List(Of String)
list.Add("testing2")
list.Add("chad")
list.Add("testing")
container.Add(list)
HttpContext.Current.Response.ContentType = "application/json"
Return New Data(HttpContext.Current.Request("sEcho"), 2, 2, container)
End Function
Public Class Data
Private _iTotalRecords As Integer
Private _iTotalDisplayRecords As Integer
Private _sEcho As Integer
Private _sColumns As String
Private _aaData As List(Of List(Of String))
Public Property sEcho() As Integer
Get
Return _sEcho
End Get
Set(ByVal value As Integer)
_sEcho = value
End Set
End Property
Public Property iTotalRecords() As Integer
Get
Return _iTotalRecords
End Get
Set(ByVal value As Integer)
_iTotalRecords = value
End Set
End Property
Public Property iTotalDisplayRecords() As Integer
Get
Return _iTotalDisplayRecords
End Get
Set(ByVal value As Integer)
_iTotalDisplayRecords = value
End Set
End Property
Public Property aaData() As List(Of List(Of String))
Get
Return _aaData
End Get
Set(ByVal value As List(Of List(Of String)))
_aaData = value
End Set
End Property
Public Sub New(ByVal sEcho As Integer, ByVal iTotalRecords As Integer, ByVal iTotalDisplayRecords As Integer, ByVal aaData As List(Of List(Of String)))
If sEcho <> 0 Then Me.sEcho = sEcho
Me.iTotalRecords = iTotalRecords
Me.iTotalDisplayRecords = iTotalDisplayRecords
Me.aaData = aaData
End Sub
Возвращенный JSON:
{"__type":"Data","sEcho":0,"iTotalRecords":2,"iTotalDisplayRecords":2,"aaData":[["testing","chad","testing"],["testing2","chad","testing"]]}
Ответы
Ответ 1
Я изменил данные на
"data": "{'sEcho': '"+ aoData[0].value + "'}",
и это сработало. Итак, теперь вопрос заключается в том, как передать остальную часть данных веб-сервису. Я попытался использовать JSON2, чтобы превратить JSON в строку, но это открыло еще одну банку червей и является отдельной проблемой.
Ответ 2
В вашем javascript-коде есть как минимум две проблемы:
- "data": "{'sEcho': '" + aoData [0].value + "'}",
Это уже указывал Чад. Это правильный способ получить sEcho:
- "success": function (msg) {fnCallback (msg.d); }
Если вы используете последнюю версию .net(я считаю, 3.5 и выше), вам нужно настроить функцию успеха, чтобы вернуться правильно. Прочитайте этот, чтобы понять, почему вам нужно передать "msg.d".
Вот ваш код js обновлен:
$("#grid").dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"bServerSide":true,
"sAjaxSource": "GridTest.asmx/ServerSideTest",
"fnServerData": function(sSource, aoData, fnCallback) {
$.ajax({
"type": "POST",
"dataType": 'json',
"contentType": "application/json; charset=utf-8",
"url": sSource,
"data": "{'sEcho': '" + aoData[0].value + "'}",
"success": function (msg) {
fnCallback(msg.d);
}
});
}
});
Затем, чтобы заставить это работать на стороне сервера, я не уверен, что вам нужно будет изменить в своем коде (поскольку я не парень VB), но я знаю, что для меня работает (используя asmx webservice):
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Collections.Generic;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class GridTest : System.Web.Services.WebService
{
[WebMethod]
public FormatedList ServerSideTest(string sEcho)
{
var list = new FormatedList();
list.sEcho = sEcho;
list.iTotalRecords = 1;
list.iTotalDisplayRecords = 1;
var item = new List<string>();
item.Add("Gecko");
item.Add("Firefox 1.0");
item.Add("Win 98+ / OSX.2+");
item.Add("1.7");
item.Add("A");
list.aaData = new List<List<string>>();
list.aaData.Add(item);
return list;
}
}
public class FormatedList
{
public FormatedList()
{
}
public string sEcho { get; set; }
public int iTotalRecords { get; set; }
public int iTotalDisplayRecords { get; set; }
public List<List<string>> aaData { get; set; }
}
Класс "FormatedList" - это просто помочь с возвратом json, который преобразуется автоматически, потому что мы используем ScriptService.
Ответ 3
Я работал над одним и тем же, и мой друг помог мне с этой частью. Этот код находится в С#, но вы должны иметь возможность его переносить.
Код jQuery:
<script type="text/javascript">
$(document).ready(function() {
function renderTable(result) {
var dtData = [];
// Data tables requires all data to be stuffed into a generic jagged array, so loop through our
// typed object and create one.
$.each(result, function() {
dtData.push([
this.FirstName,
this.LastName,
this.Sign
]);
});
$('#grid').dataTable({
'aaData': dtData,
"bJQueryUI": true
});
}
// Make an AJAX call to the PageMethod in the codebehind
$.ajax({
url: '<%= Request.Url.AbsolutePath %>/ServerSideTest',
data: '{}',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(result) {
// Call the renderTable method that both fills the aaData array with data and initializes the DataTable.
renderTable(result.d);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest + ": " + textStatus + ": " + errorThrown);
}
});
});
</script>
код aspx:
<table id="grid" width="100%">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Sign</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5" class="dataTables_empty">Loading data from server</td>
</tr>
</tbody>
</table>
код позади:
// to serialize JSON in ASP.NET, it requires a class template.
[Serializable]
public class Data
{
// Yay for 3.5 auto properties
public string FirstName { get; set; }
public string LastName { get; set; }
public string Sign { get; set; }
};
[WebMethod]
public static List<Data> ServerSideTest()
{
List<Data> DataList = new List<Data>();
Data thisData = new Data();
thisData.FirstName = "Sol";
thisData.LastName = "Hawk";
thisData.Sign = "Aries";
DataList.Add(thisData);
Data thisData2 = new Data();
thisData2.FirstName = "Mako";
thisData2.LastName = "Shark";
thisData2.Sign = "Libra";
DataList.Add(thisData2);
return DataList;
}
Надеюсь, это поможет!
Следующим шагом для меня является обработка фильтров, пейджинга и сортировки. Дайте мне знать, если вы будете работать с этими частями =)
Ответ 4
Возможно, вам стоит взглянуть на решение zowen здесь http://weblogs.asp.net/zowens/archive/2010/01/19/jquery-datatables-plugin-meets-c.aspx. Он проработал синтаксический анализатор, который работает очень хорошо.
Надеюсь, что это поможет.