如何使用 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 设置以查找数据属性,而不查看其余所需的响应信息(drawrecordsTotalrecordsFilterederror)。我的记忆可能不正确,但我很确定 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访问服务器端脚本发送的其他变量,例如drawrecordsTotal等。为此我们需要为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?

jQuery / DataTables:如何更改分页颜色

如何替换 jQuery DataTables 中的数据数组

如何动态更改 jQuery Datatables 高度

如何使用 jQuery DataTables 过滤某些列

如何使用 jQuery dataTables 启用服务器端搜索?