How do you send and receive JSON with jQuery.dataTables 1.10 for ASP.NET WebMethod backend?

Version 1.10 of jQuery DataTables changes a ton of things from previous versions of DataTables, including how it handles Ajax requests and responses.

The developers of the library have no experience with the ASP.NET backend, so while some of the nuances of WebMethods have been brought to them in the past, they apparently did not consider them in this release.

For example, the dataSrc

DataTables parameter should be where we are dealing with the fact that ASP.NET WebMethods wraps all of its Ajax responses with {d: [response]}

.

Instead DataTables seeks only option dataSrc

to find the data property, and not the rest of the required information Answer ( draw

, recordsTotal

, recordsFiltered

and error

). My memory might be wrong, but I'm pretty sure the parameter is being dataSrc

used to handle this just fine.

+3


source to share


4 answers


Below is my solution. There might be an easier way to do this, but the way I set up the data tables below seemed to be the most reusable way to send and receive JSON for ASP.NET WebMethod. Please post other methods that worked for you. Hopefully someone will be less likely to do the "d" thing.

var $table = $('#TableId');
var url = 'page.aspx/WebMethodName';
var extraData = {
    something: 'value1',
    somethingElse: 'value2'
};

      

The event handler processes data from the server. I am moving everything from property d to the root of the object.

$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?
                }
);

      

Initializing DataTable. I am serializing the data to send to the server as late as possible to give me a lot of room to add to the request.



$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 });
                }
        }
    }
});

      

On the server side, I created classes to model the structure that dataTables sends and requires as a response. T is the type for each data line. DataTablesResponse has a constructor overload that takes the value of request.draw and inserts it into the response, so I don't have to remember.

[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;
}

      

As a side note, I tried to post it on the dataTables.net forums, but for some reason I can't get it for a draft ... so it will live here.

0


source


To process the JSON response from the server in format {d: { data: [] } }

, you can use the DataTables initialization option dataSrc

as follows "dataSrc": "d.data"

. However, it only works in client-side processing mode.

Client-side processing mode only

$('#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"
   }
});

      



One-stop solution
for client and server processing modes

The server-side processing mode, we need to allow DataTables to access other variables you set up to server-side script, for example draw

, recordsTotal

etc. To do this, we need to use the callback for dataSrc

and copy the properties json.d

to json

and get rid of the property 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


source


You can use EnablePageMethods in the ScriptManager and call them directly from the PageMethods object, which will not have the returned data nested in .d.

0


source


You can use dataFilter function in your ajax call to remove property d. Note that if your dataType is json then you need to bind the object back to the string as ajax will parse the returned data into json again.

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

      

0


source







All Articles