【问题标题】:How do you send and receive JSON with jQuery.dataTables 1.10 to a ASP.NET WebMethod backend?如何使用 jQuery.dataTables 1.10 向 ASP.NET WebMethod 后端发送和接收 JSON?
【发布时间】: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 设置可以很好地处理这个问题。

【问题讨论】:

    标签: asp.net ajax json datatables webmethod


    【解决方案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;
                      }
                    }
        

        【讨论】:

          猜你喜欢
          • 2020-08-14
          • 2018-12-23
          • 2018-10-06
          • 1970-01-01
          • 1970-01-01
          • 2021-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多