jQuery DataTables的1.10版本改变了以前版本的DataTables的大量内容,包括它如何处理Ajax请求和响应。
该库的开发人员没有任何使用ASP.NET后端的经验,因此尽管WebMethods的一些细微差别在过去已经提到过,但他们显然没有在这个版本中考虑它们。
例如,dataSrc
DataTables选项应该是我们处理ASP.NET WebMethods用{d: [response]}
包装所有Ajax响应这一事实的地方。
相反,DataTables仅查看dataSrc
设置以查找数据属性,而不是其他所需的响应信息(draw
,recordsTotal
,recordsFiltered
和error
)。我的记忆可能不正确,但我很确定dataSrc
设置用来处理这个问题就好了。
答案 0 :(得分:1)
要以{d: { data: [] } }
格式处理来自服务器的JSON响应,您可以使用DataTables初始化选项dataSrc
,如下所示"dataSrc": "d.data"
。
但它仅适用于客户端处理模式。
仅限客户端处理模式
$('#example').dataTable({
"ajax": {
"url": "Default.aspx/GetSearchResults",
"type": "POST",
"contentType": "application/json; charset=utf-8",
"dataType": "json",
"data": function (d) {
return JSON.stringify(d);
},
"dataSrc": "d.data"
}
});
通用解决方案
fot客户端和服务器端处理模式
在服务器端处理模式中,我们需要让DataTables访问服务器端脚本发送的其他变量,例如draw
,recordsTotal
等。为此,我们需要使用回调函数dataSrc
选项并将json.d
属性复制到json
并删除d
属性。
$('#example').dataTable({
"ajax": {
"url": "Default.aspx/GetSearchResults",
"type": "POST",
"contentType": "application/json; charset=utf-8",
"dataType": "json",
"data": function (d) {
return JSON.stringify(d);
},
"dataSrc": function(json){
for(key in json.d){ json[key] = json.d[key]; }
delete json['d'];
return json.data;
}
}
});
答案 1 :(得分:0)
以下是我的解决方案。可能有一种更简单的方法,但我在下面设置dataTables的方式似乎是向ASP.NET WebMethod发送和接收JSON的最可重用的方式。请发布适合您的其他方式。希望有人会有一种不那么糟糕的方式去做" d"的事情。
var $table = $('#TableId');
var url = 'page.aspx/WebMethodName';
var extraData = {
something: 'value1',
somethingElse: 'value2'
};
事件处理程序处理从服务器接收数据。我将所有内容从d属性移动到对象的根目录。
$table.on('xhr.dt', function (e, settings, json)
{
/// <summary>
/// Fix for asp.net WebMethod compatibility.
/// If json has a d property, then response came from a WebMethod.
/// DataTables needs the contents of the d property to be in the root.
/// </summary>
/// <param name="e">The jQuery event object.</param>
/// <param name="settings">The jquery.DataTables settings object.</param>
/// <param name="json">The data returned from the server.</param>
if(json.d)
{
var data = json.d;
// Clear out json.d to free up memory
json.d = undefined;
$.extend(json, data);
}
// Note no return - we have to manipulate the data directly in the JSON object.
// WHY, OH WHY, CAN'T WE JUST RETURN?
}
);
DataTable初始化。我将数据序列化为尽可能晚地发送到服务器,以便给自己提供大量机会来添加请求。
$table.DataTable({
ajax: {
{
url: url,
type: 'POST',
contentType: 'application/json',
processData: false, // important so the raw data makes it to the beforeSend handler
beforeSend:function( jqXHR, settings )
{
/// <summary>
/// Converts to json for transmission and adds any extra data desired.
/// </summary>
/// <param name="jqXHR">The jqXHR object.</param>
/// <param name="settings">The settings object.</param>
/// <param name="data">The data that will be sent to the server.</param>
var data = settings.data;
// I postponed the serialization as long as possible, so this is the
// last chance to attach extra data to send along
data.extraData = extraData;
settings.data = JSON.stringify({ WebMethodParameterName: data });
}
}
}
});
在服务器端,我已经创建了类来模拟dataTables发送的结构并将其作为响应。 T是每行数据的类型。 DataTablesResponse有一个构造函数重载,它接受request.draw值并将其粘贴在响应中,所以我不必记住。
[WebMethod]
public static DataTablesResponse<T> WebMethodName(DataTablesRequest request)
{
var response = new DataTablesResponse<T>(request);
// Do something to get my data
List<T> results = GetMyData();
response.data = results;
return response;
}
作为旁注,我试图将此帖子发布到dataTables.net论坛,但由于某种原因我无法通过草稿......所以它会在这里生活。
答案 2 :(得分:0)
您可以在ScriptManager上使用EnablePageMethods并直接从PageMethods对象中调用它们,该对象不会将返回的数据嵌套在.d中。
答案 3 :(得分:0)
您可以在ajax调用中使用dataFilter函数来去除d属性。注意,如果你的dataType是json,你需要将你的对象字符串化回字符串,因为ajax会再次将返回的数据解析为json。
ajax: {
type: "POST",
contentType: "application/json; charset=utf-8",
url: "...",
dataType: 'json',
dataFilter: function (data) {
//data is raw string, convert to json object first
//must return string if the dataType is set to json and the jQuery ajax will parse the returned data again
var msg = jq.parseJSON(data);
if (msg.hasOwnProperty('d')) {
return JSON.stringify(msg.d);
} else
return data;
}
}