ASMX and JSON – Common mistakes and misconceptions
AJAX, ASMX Mistakes and Misconceptions, ASP.NET By Dave Ward on March 3rd, 2010While we were recording episode 5 of Mastering jQuery, I found myself running down a lengthy list of misconceptions and potential pitfalls when it comes to using ASMX services for AJAX callbacks. After years of fielding questions revolving around that topic, I suppose I’ve developed a decent handle on the issues most often encountered.
To preemptively surface some of that commonly requested information, I’m going to publish a series of relatively short posts, each describing one mistake or misconception that I’ve seen come up frequently.
To get started, I want to cover one of the most fundamental of these misconceptions: That ASMX services can’t return JSON.
Misconception: ASMX services are limited to XML
One of the most stubbornly persistent misconceptions about ASMX services is the rumor that they are limited to returning XML. With that notion mind, many developers understandably avoid them for client-side AJAX callbacks. When every byte counts, raw JSON is always preferable to the bloat of XML.
However, the introduction of ASP.NET AJAX removed that XML limitation.
In any ASP.NET 2.0+ AJAX enabled site, one of ASP.NET AJAX’s additions is something called the ScriptService. When a ScriptService is called in the correct manner, it automatically returns its result serialized as JSON instead of XML.
In fact, these ASMX ScriptServices even accept their parameters as JSON.
The ASP.NET AJAX “ScriptService”
If you’ve created an ASMX service in the past few years, you’ve probably seen this blurb at the beginning of the default template:
// To allow this Web Service to be called from script, // using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class WebService : System.Web.Services.WebService {
Since it never explicitly mentions JSON and implies a tight coupling with ASP.NET AJAX, it’s easy to understand why the ScriptService’s true power sometimes goes unnoticed. Thankfully, that attribute does much more than simply expose ASP.NET AJAX specific functionality.
In fact, the ScriptService attribute enables all of an ASMX service’s methods to respond with raw JSON if they are requested correctly. For example, these ScriptServices can easily send and receive JSON in conjunction with a third party library, without a ScriptManager or MicrosoftAjax.js anywhere to be seen.
Two simple requirements
As I alluded to earlier, the one stipulation is that these ScriptServices only return JSON serialized results if they are requested properly. Otherwise, even a service marked with the attribute will return XML instead of JSON. I can only assume that’s part of the reason for the misconception that ASMX services cannot respond with JSON.
Scott Guthrie has a great post on the specific requirements for coercing JSON out of ScriptServices. To summarize that, requests to the service methods must meet two requirements:
- Content-Type – The HTTP request must declare a content-type of application/json. This informs the ScriptService that it will receive its parameters as JSON and that it should respond in kind.
- HTTP Method – By default, the HTTP request must be a POST request. It is possible to circumvent this requirement, but it is advisable to stick with HTTP POST requests when dealing with JSON.
That’s it.
As long as those two requirements are satisfied, anything from low-level XMLHttpRequest code, to third-party libraries like jQuery, to ASP.NET AJAX itself can easily retrieve JSON serialized data from ASMX services.
Similar 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 instead.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this" link underneath the comment you're replying to.
2 Mentions Elsewhere
- The Morning Brew - Chris Alcock » The Morning Brew #553
- ASP.NET event kalender (icm ASP.NET) - 9lives - Games Forum


Since Microsoft is urging developers to move from ASMX to WCF, you might want to take a look at this: Creating a JSON-REST service using WCF
/ Anders
I think WCF is great in situations where you can take advantage of its strengths, like when you can use the tcpBinding mode. However, WCF’s complexity makes it hard to seriously consider for simple AJAX callback functionality where a better targeted, more mature solution already exists.
ASMX is by no means deprecated or obsolete, even in .NET 4. That’s actually one of the misconceptions I’m going to cover in this series.
Thanks for your posts about using web services with json. Your older posts really helped me get a handle on the requirements and now I use them anytime I need to do ajax. It’s really quick and easy once you understand those couple of gotchas.
Even Microsoft calls ASMX a “legacy technology”. Quote from MSDN Library : [...] a legacy technology. XML Web services and XML Web service clients should now be created using Windows Communication Foundation (WCF).
However, ASMX is what I started using when first moving into SOA. I do agree that it is a great option when you don’t need the extra goodies that WCF brings, such as the ability to respond to all HTTP verbs commonly associated with REST services – PUT, DELETE, GET, POST.
I don’t think many people know that ASMX is an option for hosting simple POST-based JSON-REST services, and I do like your post. :)
The interesting thing about that MSDN entry is that it may be legacy information itself (note that it’s a .NET 3.5 entry). Check out this newer MSDN entry about ASMX “ScriptServices” in .NET 4, which doesn’t carry that disclaimer anymore.
I think a good addition to this article would be a section on the cross domain issues. I’ve recently spent couple days coming across issue of setting Content-Type when requesting data from asmx services on a different domain. First: since its cross domain you cannot use XMLHttpRequest therefore you cannot set it header information in the Jquery. So the only way I found possible was to create an HttpModule which will add Content-Type header for requests coming to that service. It ended up being a lot of hassle to figure it out, and I was wondering what are your preferences on cross domain JSON services?
When I last used a asmx ScriptService for returning JSON I noticed a severe bottleneck in the ASP.NET serialization process. It was taking forever to get the response back. I switched to generic http handlers and serialized the data with newtonsoft and gained a huge improvement with response time.
Are generic handlers known to be faster than ASMX? If you don’t need the coupling of ASP.NET AJAX and are using another library for AJAX calls are you better off with generic handlers? I would like to use ScriptMethods as opposed to generic handlers as I feel it makes my code cleaner but I don’t want to incur any unnecessary overhead.
I think it’s safe to say that HttpHandlers will always be faster than any higher level abstraction. That said, I’ve never had a performance problem with ScriptServices or JavaScriptSerializer that was related to the service layer itself.
The main reason I prefer ScriptServices to rolling my own HttpHandlers is how easily it lets me do things like this: http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/
Amen to this. :)
Do you have any insite as to why Enums have to be passed as their numeric representation? Sadly this was a deal breaker for us.
If our clients are already calling our service with the URL: blah.com/service.asmx?Param1=EnumMember1, it would be great if we could tell them to just change the content type and they would be able to get back JSON. But they also need to change the URL to: blah.com/service.asmx?Param1=3.
And since the WSDL does not contain the numberic representation of the enum values, it is kind of a crap shoot since some of our enums are not numbered in order.
Happen to know of any work arounds for this?
To learn how the JavaScriptSerializer translates various types to JSON, take a look at this MSDN entry: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer%28VS.100%29.aspx
The converter will attempt to automatically type convert input parameters. Using the System.Web.HttpCacheability enum, for example:
If you call that service with a string parameter like:
CacheSetting will be correctly set to the corresponding enum value.
I haven’t tried that with a QueryString parameter like you’re describing though. If you give it a try, I’d be interested to hear if it works for you that way or not.
That won’t work through HTTP Get. Don’t want to have existing HTTP Get clients change to HTTP Post just to get JSON data back.
Did you try it? I just tried hitting that test service with this URL:
TestService.asmx/SetCacheability?CacheSetting=NoCache
And it worked as desired.
Yeah, this is what we get for the example:
blah.com/service.asmx?Param1=EnumMember1
Do the enums and its members need any special attributes?
Sorry, I misunderstood part of what you’re after. The string to enum mapping does work, but you can’t mix QueryString parameters and JSON output.
When you set the request’s content-type to application/json, that’s describing the type of the request‘s data, not the response. ScriptServices just happen to automatically respond to a JSON input with JSON output. So, when you set that content-type, the service method only accepts input parameters as keys and values in a JSON string, not QueryString parameters.
Unfortunately, I don’t think there’s a way to coerce ScriptServices to take QueryString parameters and then return JSON results.
WCF or ASHX are better options if you need to send JSON in response to a GET. RESTful-ness aside, keep in mind that returning JSON via GET should only be used when the data requires absolutely no security considerations.
It is worth noting that (historically, anyway) there is a default cap on how much content can be returned via JSON. It can be reconfigured via a maxJsonLength attribute in your web.config. Microsoft mentions this in http://msdn.microsoft.com/en-us/library/bb763183.aspx.
Hi ,
I have implement jquery,Json,and asp.net WebSevice 2.0 using C# 2.0.
I have already use in web.config File
Further give error Message.
How can resolved it.
Error Message :-Request format is unrecognized for URL unexpectedly ending in.
#Start Error Message
Request format is unrecognized for URL unexpectedly ending in ‘/GetRecordTech’.
body {font-family:”Verdana”;font-weight:normal;font-size: .7em;color:black;}
p {font-family:”Verdana”;font-weight:normal;color:black;margin-top: -5px}
b {font-family:”Verdana”;font-weight:bold;color:black;margin-top: -5px}
H1 { font-family:”Verdana”;font-weight:normal;font-size:18pt;color:red }
H2 { font-family:”Verdana”;font-weight:normal;font-size:14pt;color:maroon }
pre {font-family:”Lucida Console”;font-size: .9em}
.marker {font-weight: bold; color: black;text-decoration: none;}
.version {color: gray;}
.error {margin-bottom: 10px;}
.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
…..
…
#End Error Message
Please help to me
Thanks & Regards
Alok Kumar Sharma
Is this error when you try to access it on VS Development Server or IIS?
Make sure you’ve got the ASP.NET AJAX Extensions v1.0 installed and the web.config updated for ASP.NET AJAX (specifically the HttpHandler change for *.asmx).
Thanks for the post, i just happened to run into this issue (well apparently not an issue) earlier today and made a mental note to figure this out sometime. And now i just stumble on your post :)
i do php.My client ex-vendor using asp.net.They said they create a web service for easy other developer.
My problem
1.Extjs doesn’t support soap request.
2.Output send using extjs return diff which are xml not soap response.
My conclusion,i make my customer php ->json ->extjs->adobe air.
Thanks for the wonderful series on asp.net + jquery.
I have successfully implemented Jquery ajax calls to the asmx web service for simple db interaction. Several problems were solved while doing it your way
1) simplicity of use
2) speed
3) data integrity
It’s a really clean solution that doesn’t involve ajax toolkit and extra work required to really understand what’s going on behind the scenes. Your gotchas:) really helped.