Never worry about ASP.NET AJAX’s .d again
AJAX, ASP.NET, JavaScript, jQuery By Dave Ward. Updated August 2, 2009Note: This post is part of a long-running series of posts covering the union of jQuery and ASP.NET: jQuery for the ASP.NET Developer.
Topics in this series range all the way from using jQuery to enhance UpdatePanels to using jQuery up to completely manage rendering and interaction in the browser with ASP.NET only acting as a backend API. If the post you're viewing now is something that interests you, be sure to check out the rest of the posts in this series.
When I recently received this message from a frustrated reader:
After hours and hours of slamming my head into the desk it turns out it was the darn "d" in the response. My home computer is on .NET 2.0 and my work computer is on 3.5. Jimminie Christmas!
I realized that the “.d” introduced in ASP.NET AJAX 3.5’s JSON responses is still all too common a stumbling block when calling ASP.NET AJAX services through a library such as jQuery. In fact, with jQuery’s popularity among ASP.NET developers on the rise, this appears to have become an even more frequent problem.
Since a lot of people are having trouble with it, I want to share one method you can use to completely isolate your code from the problem. If you bake this into an $.ajax() code snippet or otherwise use it as a template for calling ASP.NET AJAX services in jQuery, you should never have to think or worry about the “.d” again.
In this post, I will show you how to detect the “.d” and how you can completely isolate your $.ajax success handler from it.
“.d” what?
If you aren’t familiar with the “.d” I’m referring to, it is simply a security feature that Microsoft added in ASP.NET 3.5’s version of ASP.NET AJAX. By encapsulating the JSON response within a parent object, the framework helps protect against a particularly nasty XSS vulnerability.
Before ASP.NET 3.5, “ScriptServices” and page methods returned their data at the top level of the JSON response, like this:

In ASP.NET 3.5 and later, the same server-side code returns this:

For more information about the change and why the change is a good one, be sure to see my earlier post: A breaking change between versions of ASP.NET AJAX.
However, what my previous post lacks is a solution for mitigating the inconsistency entirely. Using different client-side code against 2.0 and 3.5 based services is workable, but far from ideal. Wouldn’t it be nicer to not have to worry about it?
Determining whether or not the “.d” is there
In order to isolate ourselves from the “.d”, we first need a reliable way to test for its presence. Though JavaScript provides several methods for determining this, I suggest hasOwnProperty, as recommended by Douglas Crockford.
By using hasOwnProperty, your code is protected against unexpected changes to an object’s prototype chain. Though it is an unlikely problem to encounter, it’s always best to code defensively in JavaScript. The browser is a hostile environment!
Using hasOwnProperty to test for “.d”, you might end up with something like this:
$.ajax({ type: "POST", url: "WebService.asmx/MethodName", data: "{}", contentType: "application/json; charset=utf-8", dataType:"json", success: function(msg) { if (msg.hasOwnProperty("d")) // Leave the .d behind and pass the rest of // the JSON object forward. DoSomething(msg.d); else // No .d; no transformation necessary. DoSomething(msg); } }); function DoSomething(msg) { // Do something with the response data here. // Expect it to consistently have no .d. }
This code will perform identically against any version of ASP.NET AJAX.
Unfortunately, this might still get in your way. You may not always want to use the response in a call to another function, and you’ll have to remember the conditional every time you write a success handler.
Don’t make me think
I prefer a solution that doesn’t touch the success handler at all. Then, you’re free to integrate the “.d” handling into a generic $.ajax code snippet in Visual Studio and/or easily copy-paste it between files without modification.
Luckily, jQuery provides a mechanism that allows us to do just that: dataFilter.
The dataFilter parameter to $.ajax allows you to arbitrarily transform a response just before the success handler fires. Specifically tailored to this sort of situation, it passes response data into a callback function, captures the return value of that callback, and then passes the modified data into your success handler.
Hence, you can forever stop worrying about that pesky “.d” like this:
$.ajax({ type: "POST", url: "WebService.asmx/MethodName", data: "{}", contentType: "application/json; charset=utf-8", dataFilter: function(data) { // This boils the response string down // into a proper JavaScript Object(). var msg = eval('(' + data + ')'); // If the response has a ".d" top-level property, // return what's below that instead. if (msg.hasOwnProperty('d')) return msg.d; else return msg; }, success: function(msg) { // This will now output the same thing // across any current version of .NET. console.log(msg.foo); } });
Now, regardless which of these JSON forms the server returns:
// ASP.NET 2.0 with the ASP.NET AJAX Extensions installed. {'foo':'bar'} // ASP.NET 3.5 and 4.0. {'d':{'foo':'bar'}}
Your success handler will simply receive this consistent JSON object every time:
{'foo':'bar'}
dataType: none of your business
It’s important to note the removal of the dataType parameter in the $.ajax() code above. This is required in order to prevent a double-eval of service responses containing only a single string.
Internally, jQuery uses a combination of the dataType parameter and the implicit type the response. If the dataType is "json" and typeof(response) is “string”, then jQuery uses eval() to deserialize the response.
In the example above, manually deserializing the response in dataFilter results in it being of type Object, jQuery leaves it alone, and our dataFilter’d object makes its way back to the success callback either way.
However, if the dataType is set to “json” and the “.d” sanitized response happens to be of JavaScript type “string”, jQuery will assume that it is a JSON response from the server and still needs to be deserialized. That will throw an error at best.
The solution is to simply drop the dataType parameter from the $.ajax() call. It is only needed for purposes of instructing jQuery how to deserialize the response, and we’re handling that ourselves now.
Thanks to Brett for pointing this out.
Wait, isn’t eval() supposed to be evil?
If the eval() usage gives you pause, don’t worry. For now (as of jQuery 1.3.2), this is the same mechanism that jQuery uses to deserialize JSON too. Though eval() is potentially evil, it is still a necessary evil in many browsers.
In my next post, I’ll show you how to modify this to leverage a native browser implementation of JSON.parse instead of eval(), available in some newer browsers.
That post is available now: Improving jQuery’s JSON performance and security.
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.
11 Mentions Elsewhere
- DotNetShoutout
- Reflective Perspective - Chris Alcock » The Morning Brew #379
- DotNetBurner - ASP.net Ajax
- Arjan’s World » LINKBLOG for June 30, 2009
- Weekly Web Nuggets #70 : Code Monkey Labs
- Creating a Webservice Proxy with jQuery « Life of a geek and a part-time poet
- Consuming a JSON WCF Service with jQuery « Me Too on .NET
- WCF and JSON « Wibber's Blog
- ASP.NET, AJAX i JSON « Asp.net « Web Development « Pure Development Blog
- A quick guide to have jQuery call your ASP.NET PageMethods « I Came, I Learned, I Blogged
- Using jQuery in ASP.NET applications – part 1 Web Forms | Bart De Meyer – Blog



This is a great technique, but I’m having some trouble. jQuery keeps trying to eval() the “result” from dataFilter, because the content type was JSON. But my result from my webservice (the “contents” of d) is just a string and shouldn’t be eval’ed I don’t think. Which is throwing a “parseerror” inside jquery 1.3.2 (line 3725) on this line: data = window["eval"](“(” + data + “)”);
any ideas?
Since you’ll be deserializing it yourself, you should be able to drop the “dataType” parameter from your $.ajax() call.
Internally, jQuery checks for dataType == “json” and typeof(response) == “string” before eval()’ing. So, if you drop the dataType, it shouldn’t interfere.
That fixed it thanks! This dataFilter technique is a great shim to work with jquery plugins that aren’t expecting a d wrapper. nyroModal is what I’m using this technique with because it doesn’t allow me to override the success handler of the ajax call, but it does allow me to use dataFilter.
Great, glad it was that easy.
Thanks for pointing that out. I find myself using DTOs almost exclusively these days and must not have ever tested it against a string.
I updated the post to add that change.
FYI on a related note, in asp.net ajax 4.0 the ‘d’ wrapper is still there, but the client side doesn’t mind if it isn’t there. Currently it throws if it isn’t.
You should NEVER EVER eval JSON to turn it into a JavaScript object. JSON is a data format and every JS library typically has a method to parse it.
For example, in jQuery you would use: $.parseJSON
Take a look at how jQuery currently handles the JSON coming back from $.ajax() calls (line 3,725 in 1.3.2).
Next post, I’m going to show using the browser’s native JSON.parse when available, but that only covers IE 8 and FF 3.5. Do you have a preferred JSON parsing plugin for jQuery (that performs roughly as well as eval)?
Phil is right, you should defer that decision to jQuery rather than copy the code. Even if currently eval is what it does, there are good reasons to believe it will change in the future.
It’ll change in jQuery 1.3.3, to about the same as what I’m showing in my next post (using browser native JSON.parse if available). At that point (my next post), doing it in the dataFilter will be better than what jQuery’s doing, not just copying it.
Either way, you don’t have much choice if you want to transform the data independent of the success handler. Running a transform in the dataFilter via $.ajaxSetup is a must when working with some jQuery plugins that don’t otherwise play nice with “ScriptServices” and page methods.
Hi Dave,
I wonder how you know people’s pulse! Whenever I get stuck at some problem, you come up with a solution for the same problem as if I asked you :)
It was very incidental that I got stuck with same problem now as I am using jqGrid plugin (which you suggested in mail). I’ve blogged about it here.
Thank you for the article:)
Thanks so much for this post and all your other posts. I’m looking forward to a follow-up post on this matter once jQuery 1.3.3 is released. Keep up the good work.
Great post, thanks for all your hard work, and code samples.
Excellent post!! Thanks!
There is a very simple way:
success: function(msg) {
try {
if (msg.hasOwnProperty(“d”))
msg = msg.d;
}catch(ex){}
DoSomthing();
}
I don’t think the try/catch does anything there, does it? msg.hasOwnProperty is safe to call, even if msg has no properties.
In the end, you’re better served by using dataFilter and doing this processing before the success handler. That way you can both improve the JSON parsing and not have to repeat the “.d” checking for every $.ajax call you make.
I think this fails now in Jquery 1.4 – just doing some testing, and think it fails if your server is returning a simple type, e.g. a string….
Seems that jquery 1.4 doesn’t accept non-valid JSON now, and in returning msg.d from the data filter, jquery then rejects it.
any ideas?
I haven’t had a chance to experiment with it yet myself, but I think Adam is on the right track here: http://encosia.com/2009/07/21/simplify-calling-asp-net-ajax-services-from-jquery/#comment-37801
Ah! Wish I’d found that post 2 hours ago… :)
Thanks for this. Was getting frustrated with the “d” wrapper.
I had trouble with:
if (msg.hasOwnProperty(“d”))
return msg.d
else
return msg;
I converted to:
if (msg.hasOwnProperty(“d”))
return msg.valueOf;
else
return msg;
Any thoughts on this tactic?
That should only work on the .NET 2.0 version that doesn’t include the .d. What trouble did you have with returning msg.d?
It simply did not return at all :S
FYI: Net 3.51
I seem to be hitting a very similar issue with returning msg.d.
It’s presumably either returning but not getting into the ‘success’ block or just not returning at all.
Any ideas on a way round this?
The first thing I would do in that situation is to watch the response in Firebug to see what’s coming back. If it’s not hitting your success handler at all, you might be throwing a 500 error on the server-side.
Also, double check that there are no JavaScript errors on the page.
Finally, if you’re triggering the $.ajax() call with an element that also triggers page navigation or form submission, be sure that you’re using return false or event.preventDefault to prevent that from occurring. Otherwise, the browser will usually navigate before the $.ajax() callback completes, making it seem like the $.ajax() call didn’t work. This can be especially confusing with form submissions, since they may very quickly refresh the page and it isn’t obvious that anything happened.
Daaaamn this was my fk problem all the day, saved to kill my self :( hahaha
just note:
i dunno why the response, filtering the d isn’t reco by JS, is you debug thru the response is a JSON….
THANK YOU.
I was about to blow my brains out because of this stupid design choice.
As from Jquery 1.5 I use the following to solve the .d
converters: {
// Evaluate text as a json expression
“text json”: function(data) {
var dataObj = $.parseJSON(data);
return dataObj.hasOwnProperty(‘d’) ? dataObj.d : dataObj;
}
}
actually, can be converted to:
data = data.d ? data.d : data;
You would run into trouble there if the return value was intentionally the value
falseor something ambiguously falsy like the number 0 or null.but if you return valid json structures there is no way that the value could be an unexpected ‘false’ or ‘null’, actually i use this code in almost 6 applications in different servers and different .Net frameworks and i don’t get any error, when you return a json object you know the sctructure and possible values, so you shouldn’t get any surprise.
People often return scalar values from their methods (which is valid JSON with the .d wrapper). A boolean indicating success/failure of an update is common, for example. If that method returns
false, the ternary approach would pass{ d: false }back through the dataFilter instead offalse. Same issue with any methods that might return 0 or an empty string.If you’re never returning anything but an object, the ternary should be safe, yes.
you right, but i think that return just a value there is a bad practice or bad use of JSON cause if we are talking about JSON (JavaScript Object Notation) responses, return a lonely value is the mistake (even if in javascript everything is an object).
You right, but if programmers do not understand what JSON it is then we should correct to teach the right way.
Regards!
If all your AJAX calls are using ASP.NET 3.5, the following will work:
Just keep in mind that the extra overhead from the redundant
stringifyand$.parseJSONwill become significant on larger responses, which can lead to visible stutters in your interface since JavaScript and the browser’s rendering engine run together in a single thread.I’m assuming this same technique can be used with a GET and instead of the .d, a cruft such as “for(;;)” or “while(1);” ?
Working with ASMX “ScriptServices” and ASPX page methods, there’s no much choice, because you’ll always be POSTing and the
.dis added at the framework level.It might make sense to manually add something like this to sensitive GET-able endpoints under MVC or Web API though.
Use JSON.parse instead of eval everywhere, always. Encouraging any use of eval promotes bad programming practices.
That’s easy to say now that you’re much more likely to be primarily targeting browsers that support native
JSON.parse. At the time this was written, nativeJSON.parsewas a relatively new feature. jQuery itself still usedeval()to deserialize all JSON responses at this time, even if the browser did have nativeJSON.parsesupport (in fact, my next post on this topic discussed extending this approach to use native JSON.parse when available).For that matter, even Crockford’s json2.js uses
eval()in its implementation of JSON.parse (after a bit of input sanitizing). There were parse-only implementations floating around, but it turned out to be prohibitively slow in the older JavaScript engines that need JSON.parse polyfilled.I suppose what I’m saying is that you have to be careful about making blanket statements about
eval(); especially in historical context. “Eval is evil” comes from Crockford, but his own acceptance ofeval()for JSON evaluation played a critical role in JSON being a viable format in the first place.thank you very much i was wasted hours