如何使用jQuery.dataTables 1.10向ASP.NET WebMethod后端发送和接收JSON?

时间:2014-12-23 19:32:58

标签: asp.net ajax json datatables webmethod

jQuery DataTables的1.10版本改变了以前版本的DataTables的大量内容,包括它如何处理Ajax请求和响应。

该库的开发人员没有任何使用ASP.NET后端的经验,因此尽管WebMethods的一些细微差别在过去已经提到过,但他们显然没有在这个版本中考虑它们。

例如,dataSrc DataTables选项应该是我们处理ASP.NET WebMethods用{d: [response]}包装所有Ajax响应这一事实的地方。

相反,DataTables仅查看dataSrc设置以查找数据属性,而不是其他所需的响应信息(drawrecordsTotalrecordsFilterederror)。我的记忆可能不正确,但我很确定dataSrc设置用来处理这个问题就好了。

4 个答案:

答案 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访问服务器端脚本发送的其他变量,例如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;
      }
   }
});

答案 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;
                }
            }