A breaking change between versions of ASP.NET AJAX
AJAX, ASP.NET, JavaScript, jQuery By Dave Ward on February 10th, 2009When working directly with JSON serialized ASMX services, be it via jQuery, pure XmlHttpRequest calls, or anything else other than the ScriptManager, one question inevitably arises. That question is of the inexplicable .d attribute that appeared in ASP.NET 3.5.
What is it? Why is it there?
In this post, I’ll use both a 2.0 and a 3.5 example ASMX web service to illustrate exactly what’s going on. I’ll also show you why it’s a good change.
An example
Following a concrete example always helps to better clarify these things. For that purpose, let’s assume that we want to call a web service and retrieve an instance of the following Person class:
public class Person { public string FirstName; public string LastName; }
The ASMX web service to return an instance of that class could be simple as this:
[ScriptService] public class PersonService : WebService { [WebMethod] public Person GetPerson() { Person p = new Person(); p.FirstName = "Dave"; p.LastName = "Ward"; return p; } }
Because our WebService class is decorated with the [ScriptService] attribute, the ASP.NET AJAX Extensions (System.Web.Extensions) will automatically serialize the return value as JSON if properly requested.
Note: A common anti-pattern that I’ve seen in practice is using a return type of string and returning a manually JSON serialized object. Don’t. It’s unnecessary and results in doubled effort on both the server and in the browser.
Let the framework handle this task unless you have a good reason not to use the built-in functionality. It works just fine in most scenarios.
Calling the service and inspecting its result
Using jQuery to consume an ASMX web service is simple, but does require jumping through a few hoops. We can use this jQuery to consume the Person service we just created:
$.ajax({ type: "POST", contentType: "application/json; charset=utf-8", url: "PersonService.asmx/GetPerson", data: "{}", dataType: "json", success: function(msg) { // Do interesting things here. } });
Making that call against an ASP.NET 2.0 site with the ASP.NET AJAX Extensions 1.0 installed, this JSON object would be the return value:

I find that it often helps to visualize the JSON in a more human readable format. This is the same JSON object as seen in the Firebug screenshot above:
{"__type" : "Person", "FirstName" : "Dave", "LastName" : "Ward"}
Within the success callback shown above, you may access properties of the Person exactly as you would expect. For example, msg.FirstName will evaluate to “Dave”.
Waiter, there’s a .d in my msg soup!
Eventually, you’ll finally convince management to let you upgrade the site to ASP.NET 3.5. After all, you can use an object initializer to cut the size of the web service in half!
However, your msg.FirstName statement now results in the dreaded undefined.
What happened? Let’s inspect the ASP.NET 3.5 response in Firebug:

The entire Person object is wrapped within a new “d” object now. Alternatively we might visualize it this way:
{"d":{"__type" : "Person", "FirstName" : "Dave", "LastName" : "Ward"}}
As you’ve probably figured out by now, the solution is to reference the property as msg.d.FirstName now. In our example, this will again resolve correctly as “Dave”.
This is the case with all ASMX services JSON serialized through the ASP.NET AJAX Extensions in ASP.NET 3.5. Even if you’re only returning a scalar return value, such as a string, int, or boolean, the result will always be enclosed within the “d”.
Why did it change?
While I wish this unexpected change had been more clearly announced, it’s a good one. Here’s how Dave Reed explained it to me:
{"d": 1 }
Is not a valid JavaScript statement, where as this:
[1]
Is.
So the wrapping of the "d" parameter prevents direct execution of the string as script. No Object or Array constructor worries.
[] is JavaScript’s array literal notation, allowing you to instantiate an array without explicitly calling a constructor. To expand on Dave’s explanation, simply consider this code:
["Dave", alert("Do Evil"), "Ward"]
That literal array declaration will execute the alert in most browsers. Danger!
Update: For an even better description of why the .d is important, from Dave Reed himself, be sure to see his comment below.
Conclusion
I hope this post has helped clarify any confusion caused by the “d” in ASP.NET 3.5’s JSON serialized ASMX services, and made you aware of why it’s worth the hassle. As sophisticated as XSS exploits have become in recent years, unexpected script execution has the potential for devastating consequences. That extra “d” is well worth the short-term hassle.
Microsoft often catches flak over security related issues, but rarely gets credit when they do things right. I, for one, think the ASP.NET team deserves credit for remaining vigilant and often preempting these exploits for us.
Thanks, guys.
Possibly related posts
What do you think? Your comments are welcome.
I appreciate all of your comments, questions, and other feedback, 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 an existing comment, please use the threading feature. To do this, click the "Reply to this comment" link underneath the comment you're replying to.
6 Mentions Elsewhere
- Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew
- DotNetShoutout
- Cross Site Scripting » Blog Archive » A Breaking Change Between Versions of Asp.Net Ajax | Encosia
- JavaScript Arrays via JQuery Ajax to an Asp.Net WebMethod | Elegant Code
- jQuery + ASP.NET Web Service : data.d or not d? | 亞特蘭提斯 Net Atlantis
- myBlog » Blog Archive » jQuery + ASP.NET Web Service : data.d or not d?


Thank you for explaining that. I’ve recently started using ASMX with ExtJs, and wondered what the ‘d’ was all about, and whether I could rely on the returned object always being wrapped in the ‘d’. When using the AJAX Control Toolkit and the ScriptManager, that detail was hidden from me.
BTW: we use ExtJs on pages that require their widgets (e.g. the fantastic grid). And we use jQuery on those pages where we don’t use UI widgets, just straight JavaScript, sometimes with ASMX calls, sometimes with controls from the ASP.NET AJAX Control Toolkit (e.g. Calendar, AutoComplete extender).
My view at the moment is that jQuery is the library to go for, and with Microsoft’s backing, the one which will become dominant (when working with ASP.NET, at least). But their widget plugins aren’t as sophisticated as ExtJs’s yet, from what I’ve seen. E.g. ExtJs grid is way ahead of jqGrid. I expect that situation to change over the next year or two.
I had seen that and wondered what on earth it was there for. Thanks for clearing it up David :)
Thanks for information.
Thanks a lot for explaining this mystery. I usually just eval msg.d into a new variable for readability, but now I know where the d actually comes from :)
Thanks for explaining!
Thanks for the explaination, Dave. :)
It’s one of those security features that has a very easy to misunderstand purpose. The protection isn’t really against accidentally executing the alert in your example. Although that is one benefit of ‘d’, you’d still have to worry about that while evaluating the JSON to convert it to an object.
What it does do is prevent the JSON response from being wholesale executed as the result of a XSS attack. In such an attack, the attacker could insert a script element that calls a JSON webservice, even one on a different domain, since script tags support that. And, since it is a script tag afterall, if the response looks like javascript it will execute as javascript. The same XSS attack can overload the object or array constructors (among other possibilities) and thereby get access to that JSON data from the other domain.
To successfully pull that off, you need (1) a xss vulnerable site (good.com) — any site will do, (2) a JSON webservice that returns a desired payload on a GET request (e.g. bank.com/getaccounts), (3) an evil location (evil.com) to which to send the data you captured from bank.com while people visit good.com, (4) an unlucky visitor to good.com that just happened to be logged into bank.com using the same browser session.
Protecting your JSON service from returning valid javascript is just one thing you can do to prevent this. Disallowing GET is another (script tags always do GET). Requiring a certain HTTP header is another (script tags can’t set custom headers or values). The webservice stack in ASP.NET AJAX does all of these. Anyone creating their own stack should be careful to do the same.
In case you’re reading this and aren’t aware of Dave Reed’s involvement on the ASP.NET team, his comment above is the definitive word on this.
Thanks for the awesome explanation, Dave!
Thank you so much! I saw that some time ago and never could figure out what was going on. I tried googling it, but good luck when one of your search terms is simply the letter “d”.
Nyce…
Thanks! Gracias! Merci! Danke!
This causes problems with LINQ objects from a dbml though. Serializing anything that has an association causes an exception.
So faced with a choice to recreate my own object or do a little manual JSON serialization I don’t think it’s that bad of an option (the latter)
Unless its just me, which it totally could be :)
When I want a subset of properties like that, I usually use LINQ to select out an anonymous type and return IEnumerable. This way you not only control what data is returned, but you eliminate the extraneous __type data.
(BTW, +1 for getting the quote markup right!)
When i was using 2.0, i can get the value of my JSON object:
var jsonText = ‘{\”a\”:[{\"Abbr\":\"4D\",\"Name\":\"4D Lottery\"}]}’
var jsonObj = JSON.parse(jsonText)
->Using jsonObj.a[0].Name i can retrieve “4D Lottery”.
But now with the additional “d” object:
var jsonText = ‘{“d”:”{\”a\”:[{\"Abbr\":\"4D\",\"Name\":\"4D Lottery\"}]}”}’
var jsonObj = JSON.parse(jsonText)
How can i retrieve “4D Lottery” value?
jsonObj.d.a[0].Name
Cannot. It seems like the json.js or jquery1.3.1.js have problem with the “d”.
http://localhost:3041/SGAccounting/js/json.js Event thread: BeforeExternalScript Syntax error while loading: line 190 of linked script at http://localhost:3041/SGAccounting/js/json.js : var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u --------------^,
That error means that something is breaking the RegEx in that line of json.js, causing a syntax error.
Have you tried using json2.js to parse your JSON instead? It may fix whatever bug you’re running into here.
Ultimately, you probably don’t need to use that JSON parser at all. Between jQuery on the client-side and System.Web.Extensions on the server-side, the serialize/deserialize operations should all be covered.
Great as always Dave…
After so many hours, i realised that it worked when passed res.d. Thks anyway. Can you show me the Person example in vb? Currently, i serializ the JSON object manually.
Something like this:
i think that microsoft product is more secure than before!
I tried this in my test web service running under .net v.2 + ajax extensions v.1 installed and it didnt work. What I see in docs, it has json serializer, but it is not using it to serialize web methods responses. This feature is working on .net v3.5. though.
So, did I miss something?
Make sure your web service is decorated with the [ScriptService] attribute. It won’t return JSON without that attribute.
As I posted the comment in “Using jQuery to Consume ASP.NET JSON Web Services”, is there any better solution to make the older and new version all work well for that jQuery ajax call?
To insulate your code against the change, you can do something like:
Thanks a lot, I just can do it this way adn have applied it. :)
thanks, I’m using jquery1.3.2 and asp.net 2.0 ,when I tried this in my web service running under .net v.2 + ajax extensions v.1. installed and it didn’t work. finally I got help from this document, it’s the “.d” different from extensions v1 to extensions v3.5
Hi, I follow your example, but get the “text/xml” response instead of JSON:
Dave
Ward
Is there anything I ignore?
By the way I am using ASP.NET 2.0 AJAX Extensions 1.0.
Thanks a lot.
Thanks for posting your work. It’s greatly appreciated. I’m hung up on this article in relation to the one on using jTemplates as a repeater.
I’m having a heck of a time getting it to work.
Basically calling a webservice:
get back in Firebug (when d is stripped out):
I’m using the jTemplate provided in your article as is (except inserting ProductId)
Getting nothing back, just an “uncaught exception 901″
My page is calling it like this:
$.ajax({ type: "POST", contentType: "application/json; charset=utf-8", url: "MyProd.asmx/HelloWorld", data: "{}", datatype: "json", dataFilter: function(data) { var msg = eval('(' + data + ')'); if (msg.hasOwnProperty('d')) return msg.d; else return msg; }, success: function(msg) { $('#Container').setTemplateURL('/templates/mytemp.htm'); $('#Container').processTemplate(msg); } });I have tried it with and without the datatype
Ideas?
What’s the return type of your service method? It looks like you’re probably double-serializing the data. You don’t have to manually invoke the JavaScriptSerializer class in your method. That’s automatically performed for “ScriptServices”.
I have the return type as string.
I removed the JavaScriptSerializer class and made it a return type of IEnumerable.
:)
Since I’m taking care of my “d” by Filtering it out (thanks to the datafilter)… my jTemplate should not reference it either. (BIG GOTCHA)
So instead of:
it becomes
so when I iterate… it works.
Thanks for catching that. I’ll try to post my solution in a more generic sense when I’m done.
Thanks a bunch!
Hi I am trying to let my webservice call another remote webservice (with identical input parameters and return types) by using HttpWebRequest and GetRequestStream.
Then I need to feed the HttpWebrequest with a post of Json serialized parameters and handle the deserialisation myself as would normally be done by javascrip on the client side.
Calling and getting the response from the remote webservice works perfect my only problem is that I want to pass the JSON parameter line invoking my webservice and pass that on to the next webservice without an extra serializing in between. Likewise I like to use the returned JSON serilized response to be directly back to the client side.
I have tried to write back Context.Response.Write(“{\”d\”:\”xx\”}”);
But it always returns missing d …
Likewise I have no idea on how to pick up the input Json parameters
Any ideas would be welcome
Regards
Martin
I think you would be better off using XML for the server-side to remote service call. You can use something simple like LINQ to XML to abstract the details of that away (see this post for an example of that), then return that data to the client-side as JSON like normal.
I forgot to mention why I am doing this, it is a piece of legacy code which has a few intrinsic problems which are difficult to resolve and the site goes down once in a while. Rewriting it all is the best solution but expensive. I have identified a few vulnerable service calls and by having an extra webservice in between it doesn’t matter if the remote webservice goes down, the site that the users see will stil be alive. By handling timeout etc I can handle the problem in a better way is my theory :)
the overhead of serializing/deserializing will not very high anyway, changing the last webservice to xml and use linq will make it easier to make the webservice call but will not improve performance ?
The two academic questions are still,
1) Is there a way to return result from a webservice in raw mode. Like Context.response.Write or similar (so I can pass the json returns from the called webservice directly instead bypassing the Json serializing that normally happens automatically when you return.
2)Pick up the Json call parameters from the client Ajax caller for the webservice inside the webservice itself. Like Context.Request .. ?
Martin
There isn’t a way to drop to that low a level in ASMX services (which is part of their beauty).
You could definitely do that with an HttpHandler though. If you did that, also keep in mind that you can use the JavascriptSerializer class yourself to serialize and/or deserialize JSON within that low-level handler.
Can you post your entire solution as downloadable source code?
Mine is not working correctly and I want to see what the heck I am doing wrong.
thanks!
It’s not polished at all, but this is the code you see in the “.d” example:
http://encosia.com/source/json-test-3.5.zip
You may be better served by looking through the jQuery category here and looking at the other examples that include source.
If it’s specifically the “.d” that’s causing you trouble, be sure to see this post in particular: Simplify calling ASP.NET AJAX services from jQuery