如何使用 jQuery.dataTables 1.10 向 ASP.NET WebMethod 后端发送和接收 JSON?
Posted
技术标签:
【中文标题】如何使用 jQuery.dataTables 1.10 向 ASP.NET WebMethod 后端发送和接收 JSON?【英文标题】:How do you send and receive JSON with jQuery.dataTables 1.10 to a ASP.NET WebMethod backend? 【发布时间】:2015-02-21 23:28:27 【问题描述】:1.10 版的 jQuery DataTables 与之前的 DataTables 版本相比进行了大量更改,包括它如何处理 Ajax 请求和响应。
该库的开发人员没有任何使用 ASP.NET 后端的经验,因此尽管过去曾向他们提出 WebMethods 的一些细微差别,但他们显然没有在此版本中考虑它们。
例如,dataSrc
DataTables 选项应该是我们处理 ASP.NET WebMethods 用d: [response]
包装其所有 Ajax 响应这一事实的地方。
相反,DataTables 仅查看 dataSrc
设置以查找数据属性,而不查看其余所需的响应信息(draw
、recordsTotal
、recordsFiltered
和 error
)。我的记忆可能不正确,但我很确定 dataSrc
设置可以很好地处理这个问题。
【问题讨论】:
【参考方案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"
);
通用解决方案支持客户端和服务器端处理模式
在服务器端处理模式下,我们需要让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;
);
【讨论】:
只有在响应中只有数据时才有效。如果您使用服务器端处理进行排序/过滤/分页,则不起作用。 这对其他所需的服务器端值没有帮助。属性 draw、recordsTotal、recordsFiltered 和 error 也都位于 d 中。 dataSrc 属性只指向数据值所在的位置。 @Somna,我明白你现在的意思了,这是有道理的。我会更新我的答案。 这就是解决方案。太棒了【参考方案2】:您可以在 ScriptManager 上使用 EnablePageMethods 并直接从 PageMethods 对象中调用它们,该对象不会将返回的数据嵌套在 .d 中。
【讨论】:
【参考方案3】:以下是我的解决方案。可能有更简单的方法可以做到这一点,但我在下面设置 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?
);
数据表初始化。我序列化数据以尽可能晚地发送到服务器,以便给自己充足的机会添加到请求中。
$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 论坛,但由于某种原因我无法让它通过草稿......所以它会放在这里。
【讨论】:
这是我的回答。创建问题时,我使用了回答您自己的问题选项。我很想看看是否有人有更好的答案,但这个问题主要是为了帮助有同样问题的人。 是的。顺便说一句,您的 WebMethod 不再受支持。你应该切换到ASP.NET Web API。 啊。在这种情况下,您将不得不坚持使用 WebMethod,或者运行一个单独的 .NET 4 站点。但另一方面,Sharepoint 2010 已有 5 年历史(而且使用起来基本上很糟糕)。显然,升级 Sharepoint 是一项艰巨的任务,但如果您还没有这样做,您应该考虑这样做。 Sharepoint 2013 使用起来很愉快。或 Office 365。 我同意.. 但不是我的选择。我非常想念asp.net MVC! 呃...我不认为页面方法会去任何地方。我知道您可以使用 Web API,但查看 MSDN ScriptManager 仍然支持 EnablePageMethods,并且没有注意到它已过时。【参考方案4】:您可以在 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;
【讨论】:
【参考方案5】:自定义返回类似d字符串,只是格式化响应
ajax =
"url": currentPage+`/method`,
"contentType": "application/json; charset=utf-8",
"type": "Get",
"dataType": "json",
"dataSrc": function(json)
let r = JSON.parse(json.d)
return r;
【讨论】:
以上是关于如何使用 jQuery.dataTables 1.10 向 ASP.NET WebMethod 后端发送和接收 JSON?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jQuery.dataTables 1.10 向 ASP.NET WebMethod 后端发送和接收 JSON?