jQuery 1.5′s AJAX rewrite and ASP.NET services: All is well
AJAX, ASP.NET, jQuery By Dave Ward. Posted February 2, 2011jQuery 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.
Similar posts
What do you think?
I appreciate all of your comments, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to another comment, use the threading feature by clicking "Reply to this comment" before submitting your own.
4 Mentions Elsewhere
- Tweets that mention jQuery 1.5′s AJAX rewrite and ASP.NET services: All is well - Encosia -- Topsy.com
- Feb 2nd Links: Visual Studio, ASP.NET, ASP.NET MVC, JQuery, Windows Phone « Naimish Pandya [MCTS, MCPD]
- Enlaces de Febrero: Visual Studio, ASP.NET, ASP.NET MVC, JQuery, Windows Phone « Thinking in .NET
- Wiązka (pokaźna) ciekawych linków z domu | Wiadomości o technologiach IT



First of all thank you for this article.
About custom JSON parsing, you have 3 ways to make it work:
1) set the dataType as text and use the dataFilter as usual
2) override the text to json converter globally:
3) override the text to json converter in the options:
As to the “.d” dataFilter, a nice way to do so with converters is to (implicitly) create a new dataType:
then use the dataType in your requests:
You could even use it through jsonp calls like this:
Hope it makes things a bit clearer about what can be achieved with converters.
I use dataFilter to correctly deserialize MS’s date format.
The function that parses it looks like this:
In 1.4, I use this from a dataFilter like so:
This parse still works as expected, but because 1.5′s dataFilter now expects me to return text, the success function now gets null.
Removing the dataFilter and replacing it with this solved the concern:
You could also let the exception propagate, ajax will use it and call the error callbacks ;)
Cross-domain Ajax doesnt work in the new jQuery. Even a simple html page with an Ajax call will not work if opened from Win 7 desktop.
That’s because 1.5 tests ahead of time if the environment supports CORS. Since the test is inconclusive in Win 7 Gadgets (a non-supported environment), jQuery.support.cors is false and the rewrite doesn’t attempt to make the request (the transport thinks it cannot handle the request).
You can override this behavior by setting jQuery.support.cors to true after you loaded jQuery. If jQuery is not 1.5+, it’ll have no impact on it so it’s perfectly safe.
Dave, whlie I am aware you are mainly a ASP.NET dev, from the research you have done I assume you may happen to know: does the new jQuery is also safe for non ASP.NET AJAX calls, i.e. PHP and other environments?
Thanks!
Skimming Stack Overflow for the past few days, I haven’t noticed people running into much trouble. I updated to 1.5 here on this site, which uses JSONP to request my Twitter status, and that code kept working fine under 1.5.
Doesn’t work ….
Can you check my StackOverflow question about it :
http://stackoverflow.com/questions/4895209/correct-web-config-for-post-webmethod-with-ajax
Unless I’m misunderstanding, your problem didn’t stem from jQuery 1.5′s AJAX rewrite did it?
Also, if you’re exclusively using jQuery to request the page method(s), you can remove the EnablePageMethods=”true” property on your ScriptManager. That’s only necessary if you’re using MicrosoftAjax.js to call the methods, and results in superfluous JavaScript being injected into the page to facilitate.
Hi Dave,
I was using the old JSON parsing dating back to v 1.3 so my code broke. I’ve adjusted my ajax helper method as below, which now works. However I’m having to explicitly call serialize and deserialize using the MS AJAX library. Is there a more efficient way to do this using inbuilt methods in jQuery?
If you’re still using MicrosoftAjax.js for other things anyway, it’s okay to leave the Sys.Serialization calls. If you’re not using MicrosoftAjax.js and you don’t need the special DateTime handling necessary for JavaScriptSerializer’s dates, you can switch to using the standard JSON.stringify() and JSON.parse() methods:
The catch is that JSON.stringify() and JSON.parse() aren’t implemented in older browsers. You’ll need to include json2.js in browsers that don’t implement it.
Thanks Dave, in that case I’ll leave it as it is for now!
You could also use a prefilter:
Please note that if you have an MVC site which is using the now-included-by-default jquery-validation plug-in, it is incompatible with jQuery 1.5 ajax calls. It vill break you. You’ll have to pull the latest plug-in files (1.7+) off of the repository: https://github.com/jaubourg/jquery-validation
Hope it helps someone.
There was problem with Ajax sending data through jQuery.Form plugin, which were cured by moving to new version.
http://www.codemastersintl.com/Blogs/Andrey-Kuleshov/2011/2/8/first-look-at-jquery-15-
Also, jQuery 1.5 did not work so well with ‘$’ in identifiers of DOM elements, so we just got rid of them.
Oddly I have to return json from my dataFilter rather than an object:
e.g.
If I just return msg or msg.d, my success function’s first parameter is null. Using the method above, the result parameter is json.
It might just be a transcription error, but that dataFilter parameter should be an anonymous function callback instead of an object literal.
hi dave,
could you please write a blog post that guides on how to handle ms json results (.d property; as well as \/Date()\/) with what jquery version (using success, datafilter, converters, ajaxprefilter or whatever).
thanks, toebens