On the bright side, your great feedback in both posts’ comments has reinforced the fact that some of the best content on my blog is the part that you write.

In this post, I’m going to detail three of the problems that were discovered as a result of those previous two posts:

An extra requirement when making a read-only request to IIS6+.

An oddity in Internet Explorer 7’s XmlHttpRequest class.

A common mistake when passing JSON parameters through jQuery.

Finally, I’ll suggest what I now believe to be a best practice usage, taking all of these issues into account.

Security requirements when POSTing to IIS

This error message was the most common problem that was reported:

Length Required

The underlying issue is that most installations of IIS6+ require a content-length be provided with all POST requests, even if there is no content (POST data).

The content-length for a request with no data should be 0, but jQuery doesn’t set that header automatically unless there is a data parameter. Since ASP.NET AJAX’s JSON serialized services require a POST request, this becomes a stumbling block for read-only requests.

The easiest way I’ve found to work around this is to use an empty JSON object as a parameter on read-only requests. For example, if you were calling a page method:

The reason for the beforeSend delegate is due a quirk in jQuery which causes it to send a specified content-type only if there is also a data parameter specified.

For security reasons, ASP.NET AJAX will not provide a JSON serialized response unless the proper content-type is provided. By using the beforeSend delegate as shown, the content-type will be manually set on the XmlHttpRequest object, before the request.

However, the new XmlHttpRequest class in Internet Explorer 7 doesn’t implement setRequestHeader very intuitively. Instead of setting the specified header, it appends the value.

This becomes a problem when you make a request that includes a data parameter. When POST data is provided, jQuery will automatically set the content-type to its default of application/x-www-form-urlencoded. In the beforeSend delegate, the required application/json; charset=utf-8 will be appended after jQuery’s default.

End result? Because this amalgamation of content-types isn’t what ASP.NET AJAX expects, the web service will not return JSON serialized content and jQuery will be unable to parse it.

Solution? If you’re sending data in your request, use jQuery’s contentType parameter to set the content-type, so that the default is never added:

JSON, objects, and strings: oh my!

In requests made to them, ASP.NET AJAX script services and page methods understand and expect parameters serialized as JSON strings. These parameters are parsed out of the POST data and used as arguments to the method you’ve called.

However, if you directly provide a JSON object as the data parameter for an $.ajax call, jQuery will attempt to serialize the object instead of passing it on to your web service.

Because that data parameter is a valid JSON object, calling the web service this way won’t throw any errors. Unfortunately, it won’t have the desired result either. Instead of passing that JSON object through to the web service, jQuery will automatically serialize and send it as:

fname=dave&lname=ward

To which, the server will respond with:

Invalid JSON primitive: fname.

This is clearly not what we want to happen. The solution is to make sure that you’re passing jQuery a string for the data parameter, like this:

In either of these cases, substitute PageName.aspx for ServiceName.asmx and PageMethodName for WebMethodName if you want to call a page method instead of a web service.

Conclusion

I hope this post will help you to avoid these common problems when using jQuery with ASP.NET AJAX. I think there’s a great synergy between the two that is certainly worth jumping through these few hoops.

I’d especially like to thank Martin and Ryan for their invaluable feedback, leading to two of the three solutions posted above.

If you’ve run into related problems yourself, I’m eager to hear about them. Please don’t hesitate to comment if you think I’m still missing something important.

Test pilot wanted

Looking for people who is interested in auto sport to become a TestFlight pilot for up-coming new release of AR1 iPhone APP.
During the TestFlight you will have access to the latest auto news and content from iPhone.