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 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:

1

2

3

4

5

publicclassPerson

{

publicstringFirstName;

publicstringLastName;

}

The ASMX web service to return an instance of that class could be simple as this:

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.

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:

1

2

3

{"__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:

1

2

3

{"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:

1

["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.

Share

Your turn. What do you think?

A blog isn't a blog without comments, but do try to stay on topic.
If you have a question unrelated to this post, you're better off posting it on
Stack Overflow instead of commenting here.
Tweet or email me a link to your question there and I'll try to help if I can.

71 Comments

Andrew Webb

3:48 am - February 10, 2009

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.

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.

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.

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)

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”.

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.

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?

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

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”.

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

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 .. ?

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.

Hi thank you for the great blog. We have just moved our web services over to 3.5 from 2.0.
We use the asynchronous jscript call backs everywhere in a fairly sizeable project. Some call backs return-value does carry this .d explained above and some don’t. From looks of things when the service call should return a basic type (like Boolean, String, Integer) then the .d appears but when the service call returns our own object like a person class (like in your example) we see the properties on the root of the returned argument. I.e. we get the person class back without the .d
Did you come across anything like this before? Would you know why this is happening? The reason why it’s causing a problem for us is because the project is massive and if we have to go through and change all the call backs, I would like to direct the team to make a standard change. Or at least understand why there is a .d in some cases and there isn’t one in others. Thanks for your help.

my $.ajax and data.d is working just fine until today!
I try to replace $.ajax with $.post, it still calls the web service and return.
BUT! my data.d disappear! not found in firebug, what is going on!?

You can’t use $.post, because it doesn’t allow you to set the Content-Type (unless you’re doing that in $.ajaxSetup). Without calling it with a Content-Type of application/json, your service will return XML instead of JSON.

Hi ,
I have one doubt. If we are already using AjaxExtensions then what is the benefit to make a webservices call through jQuery. We can directly call the webmethod from the javascript side by just writing the namespace.class.methodName(data,fnOnSuccess,fnOnFail,context).

this will be of one line coding and also we donot have to bother about type and content type. it will be automatically handled by Ajax.
However, in jQuery Ajax call we have to write whole thing type, contenttype etc….

Can you please explain me the difference between them and the benefit that we get over ajax while using jQuery Ajax.

To give you that one-line syntax, the ScriptManager is embedding a script reference to a ~60 line JavaScript service proxy for every service method. View source on a page using that syntax, or take a look at YourService.asmx/MethodName/jsdebug. The complexity is only being hidden from you, not reduced.

In our project we were using update panel. Now we want to improve performance thats why we thought to implement webserivces call through javascript.
But we are using one line call ajax style. So if we use jQuery Ajax call then it will improve further speed as you said. I don’t know how to see the extra line of code inserted in run time. I have used fiddler do fiddler help me to see that.

Also one more question. suppose my webmethod expect one object (say car object) then is it possible to pass an object which is defined in server side also.
As you said data is to be passed in json format embraced in double quotes, then am i need to create car object in client side and then convert it to in json and then put it in jQuery Ajax call data field and then proceed?…

Can you explain this how should i pass one server side predefined object through jquery ajax call.

The curious thing is that typeof reponse.d is not string!!!! it’s Object.
My web service returns List and since I followed your tutorial here, I would expect it to be serialized as JSON, ie string. Why is it an object then?

Everything works perfectly, maybe I am just getting too anal, but I was under the impression that JSON always returns a string…..If not, what’s the point of eval here?

You’re right that GetSamples is returning a JSON string. When $.ajax()’s dataType is “json”, jQuery automatically deserializes it for you though. That’s a good thing, because in jQuery 1.4+, it uses browser-native JSON.parse instead of eval() if available. That is faster and more secure.

So, in 2.0 response will be a JavaScript array and in 3.5+ you’ll get back a JavaScript object such that response.d is that same array.

So just to clarify that I got all the behind-the-scenes stuff right. My Web service returns List<Sample> where Sample is an object, so it doesn’t explicitly return a string.

Then, response.d is Object as well as I noted before. So does this all mean that my web service returns a string, the jquery makes an object out of it and that’s why I get response.d as an object? What’s confusing is that I am told that JSON is always a string returned format but yet nothing in my set-up actually returns a string. Does this mean that all serialization/deserialization happens behind the scenes?

When I do
array = response.d, I can work with the array as if it’s array of objects (which it is)…so everything works fine, but I am just a bit skeptical – where is JSON here?

You’ve got it right. When you return a complex type from a “ScriptService”, .NET automatically serializes that as a JSON (or XML, if you don’t call it correctly) string and returns that string as the response. On the client-side, jQuery automatically takes that JSON and boils it down into a native JavaScript object before handing it back to you.

Watching the service’s response in Firebug (like the screenshots in the post above) is a good way to visually confirm JSON strings are what is being passed between server and client.

To see it from a different angle, you might be interested in episode 5 of my TekPub series on jQuery. We spend about an hour on the topic of using JSON services with WebForms/jQuery in that episode.

actually this is jquery for accessing webservice written in c#
but i m not getting required result. this is webmethod which returns simple hello world string. if i m accessing this webservice in browser i m getting required result but here in code it returns null value.
so plz help me out. i m getting weired.
thanx in advance…

So here is my scenario..
I am calling a webmethod from the client side using jquery ajax…
The webmethod in C# is making an httprequest to a service (Yelp)…
The service is returning a string in JSON structure…
Can I just return that string straight bcak to the client side or do I need to format it to be a true JSON object?

Thanks very much for clearing this up. It took a couple of days for me to track down why our jQuery.ajax calls had gone bad when we upgraded so it’s really nice to get the full story behind why this came about. You definitely rock! :-)

This is a really helpful post, thank you. Unfortunately I am trying to get our client to produce a JSON webservice for mobile devices—in other words, that will never be executed on a page—and this means our devices have to go through two layers of JSON decoding to get the feeds, which (on some pretty long feeds) could be a significant processing overhead on often quite small devices. Is there no way around this?

Indexing down into the .d should have negligible performance impact on any device. That’s not comparable to a second level of serialization or anything that heavy.

If you really want to get rid of the .d, consider moving to ASP.NET Web API. It’s more flexible than ASMX in general, including not forcing you to use the .d wrapper. Migrating from ASMX to Web API is very easy if you use RPC-style routing in Web API.

The bigger question is what about all the public tools that call such web methods? Have they been converted to handle that extra “level”?

I have just installed the latest AjaxControlTookkit for ASP.NET. The AutoCompleteExtender works fine but underneath the Java scripts keep reporting “Sys.ArgumentException: Cannot deserialize. The data does not correspond to valid JSON.” Is something amiss?

All of the “official” methods for making calls to page methods and ScriptServices do handle unwrapping the .d (and they don’t really need to know about both formats since the framework sends you the MicrosoftAjax.js version that’s appropriate for your .NET version.

The AjaxControlToolkit does use those “official” methods, so it should always be unaffected too. You might try looking at the JSON that’s coming back, in the network section of your favorite browser tools and see if there’s something obviously wrong with it that might be breaking the JSON deserialization. There are JSON lint tools you can use to validate the JSON too, if you aren’t sure about it.

I am new to ExtJs and WebServices. Tried to bind data to a combo using the webservies.
I am just frustrated with “d” in the jsonData. Can you please help me get rid of this and load the data in combo
My code follows:Web Service:

Thanks a lot for this, I was having a hard time trying to use my code (written for 3.5) in 2.0, I removed the “.d” and now everything works nicely. Thanks a lot, I really enjoy Jquery + Ajax + Asp.net! :D

Leave a Reply

Use <pre lang="x">code</pre> to include code blocks with syntax highlighting, where x is asp, csharp, html, javascript.
Even inside <pre> and <code> blocks, the open angle brackets in HTML and XML need to be encoded (i.e. convert any
< to &lt;).