jQuery 1.5’s complete overhaul of the AJAX API has led to several people contacting me recently, understandably nervous about how the rewrite will impact working with ASMX ScriptServices and ASPX page methods. Seeing the default calling syntax change to $.ajax(url, settings) was especially unsettling to many.

I’m happy to report that the short answer is: jQuery 1.5’s new AJAX module has almost no negative impact on any of the techniques you may have read about here. The rewrite maintains very good compatibility for the $.ajax(settings) calling syntax and for now-deprecated features such as dataFilters.

One advanced dataFilter usage appears to be broken, but it’s something that you probably already stopped using with jQuery 1.4. To be clear, I’ll briefly enumerate all of the techniques I’ve re-tested and jQuery 1.5’s impact (or lack thereof) on each.


ASMX ScriptServices and ASPX page methods

The most common way of using jQuery to communicate with an ASP.NET WebForms application today is to use an ASMX ScriptService or ASPX page method. If you’re requesting an ASMX ScriptService using the approach I originally described:

$.ajax({
  type: "POST",
  contentType: "application/json",
  url: "/YourService.asmx/YourMethod",
  data: "{}",
  dataType: "json",
  success: function(msg) {
    console.log(msg.d);
  }
});

That code will continue to work exactly as-is with jQuery 1.5. If you prefer page methods instead, you’re in the clear too.

Note: You can simplify the contentType parameter to “application/json” when using any version. The ScriptService handler only checks that the header contains “application/json”, not for an exact string match. It’s a small improvement, but noticeably easier to remember and type.

DTOs and JSON.stringify()

If you’re using jQuery and ASP.NET JSON endpoints to accomplish more complicated tasks, you may be using JSON.stringify() to simplify making requests that include data transfer objects. Paired with corresponding complex types or collections on the server-side, this approach seems almost too good to be true:

var NewPerson = { };
 
NewPerson.FirstName = $("#FirstName").val();
NewPerson.LastName = $("#LastName").val();
NewPerson.Address = $("#Address").val();
NewPerson.City = $("#City").val();
NewPerson.State = $("#State").val();
NewPerson.Zip = $("#Zip").val();
 
var DTO = { 'Person' : NewPerson };
 
$.ajax({
  type: "POST",
  contentType: "application/json; charset=utf-8",
  url: "PersonService.asmx/AddPerson",
  data: JSON.stringify(DTO),
  dataType: "json"
});

jQuery 1.5’s AJAX rewrite has not impacted that technique either. If you provide a string value for its data parameter, jQuery will pass that string on to the server unmodified.

dataFilters and “.d”

With jQuery 1.5 fundamentally revamping $.ajax()‘s extensibility model, the technique of using a dataFilter to normalize ASP.NET’s “.d” wrapper is what I worried most about surviving the 1.5 transition. That approach looked like this:

$.ajaxSetup({
  type: "POST",
  contentType: "application/json; charset=utf-8",
  data: "{}",
  dataFilter: function(data) {
    if (msg.hasOwnProperty('d'))
      return msg.d;
    else
      return msg;
  }
});
 
$.ajax({
  url: 'YourService.asmx/YourMethod',
  success: function(response) {
    // You'll never have to worry about the response being 
    //  buried in response.d here.
  }
});

Though jQuery 1.5’s new converters will probably enable a better solution, this dataFilter approach does continue to work in jQuery 1.5.

dataFilters and JSON parsing

While the simple dataFilter does work, if you’re using a dataFilter to implement custom JSON parsing, you may need to make a small change. What I mean by that is code like this:

$.ajax({
  // Your usual $.ajax() URL, data, dataType, etc.
  dataFilter: function(data) {
    if (typeof (JSON) !== 'undefined' && 
        typeof (JSON.parse) === 'function')
      return JSON.parse(data);
    else
      return eval('(' + data + ')');
  }
});

The usefulness of that approach dates back to jQuery 1.3 and earlier, when jQuery exclusively used eval() for deserializing JSON responses. At that time, it was helpful to manually override the deserialization process to take advantage of browser-native implementations of JSON.parse() when available. Doing so yielded both performance and security gains.

In jQuery 1.4, this was no longer necessary because jQuery contained a similar bit of browser-native parser testing code itself. However, the dataFilter approach above did continue to work in jQuery 1.4 $.ajax() requests, so long as the dataType for the request was either omitted or set to a value that didn’t trigger jQuery’s automatic JSON deserialization (e.g. “text” or “foo”).

As of jQuery 1.5, using this dataFilter approach for manually controlling deserialization will no longer work if the request’s dataType is set to “json” or even omitted.

Except for the most obscure of edge cases, the best solution is simply to drop this code. It’s redundant if you’re using jQuery 1.4.0 or later. Again though, you can continue using a dataFilter to handle the “.d” issue.

Conclusion

For the most part, upgrading to jQuery 1.5 is a non-issue when it comes to using $.ajax() with ASP.NET JSON endpoints. Considering the fundamental nature of the module’s rewrite, it really is commendable how well backwards compatibility has been maintained.

Once you’ve vetted your existing code for compatibility with jQuery 1.5, do be sure to check out the powerful new features that have been added to $.ajax() in this rewrite. Its new extension points, prefilters, converters, and transports, will offer finer-grained control than ever before.

Even more exciting is the AJAX rewrite’s inclusion of “deferreds”. You can count on seeing more about that here soon, but right now I highly recommend taking a look at this post by Eric Hynds.

If you’ve tested jQuery 1.5 in your own sites/projects, I’m curious if you’ve run into any issues I didn’t address. Please do leave a comment if I’ve missed anything that caused you trouble in the upgrade.