通过Jquery和ASP.NET进行Ajax

Executive Summary

context.Response.Header.Add("Content-Type", "application/json");

gets ignored while

context.Response.ContentType = "application/json";

breaks jQuery ajax calls.

====================================================================

I have an IHttpHandler that returns some JSON data and is defined as:

void ProcessRequest(HttpContext context)
{
    context.Response.Write(/* some JSON */);
}

and called using the jQuery Ajax methods like so:

$.get(SOME_URL, SUCCESS);

This works fine.

However, if the ProcessRequest method is defined thus:

void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "application/json"
    context.Response.Write(/* some JSON */);
}

it fails, meaning that the SUCCESS function in $.get(SOME_URL, SUCCESS); never fires, yet the correct content still get returned with the expected headers according to Fiddler2.

On the other hand, if the ProcessRequest method is defined thus:

void ProcessRequest(HttpContext context)
{
    context.Response.Header.Add("Content-Type", "application/json");
    context.Response.Write(/* some JSON */);
}

everything works but Fiddler2 reports that it is being returned as type "text/html".

Any idea why that happens?

NOTE: The URL is extensionless and the application is running on IIS 7.5 so I wonder whether or not the problem is related to the IIS MIME types.

An IHttpHandler is an excellent choice for implementing AJAX handlers in ASP.net. It has lower overhead than a page and is easy to setup/install compared to something like WCF web services. While you could make a classic .asmx webservice, this should have no effect on the problem you posted.

Also context.Response.ContentType = "application/json"; is the correct technique for changing the contenttype header of the HttpResponse from inside the ProcessRequest method of your handler.

Your problem will likely be a malformed response. The question is now to narrow down what is breaking the response.

  1. If you have not already done so, grab a full copy the server response using firebug, chrome developer tools, fiddler or wireshark. Using the correct technique for changing the content type highlighted above you say the ajax success event never fires, but you did not let us know if you inspected the HttpResponse for content type header, response code and valid json.
  2. Verify that the content type header was in fact set to "application/json".
  3. Double check that your json is in fact syntactically correct as sent over the wire. (Remember this must be "evaluate-able" by JavaScript
    • a misplaced bracket, quote or colon can really muck it up).
  4. Do you have any control characters or unicode text in your json? Are they properly escaped? This is a common pitfall with json, improperly escaped content or incorrect encoding. Are you using any code to convert from bytes to strings or string to bytes in your code? If so, be sure you are using the desired encoding, probably utf-8.

If you suspect that your chosen UrlRewriter technique is changing the response headers, I would hope this is relatively easy to turn off and test with an extension based URL to your handler? This would at least confirm that you are diagnosing the correct issue and that it is worth your time to further research the issue. If you confirm that the UrlRewriter is the problem, you should post a question about the specific UrlRewriter technology you are using. For example are you using something like Helicon Tech's ISAPI Reqwrite? Or Microsoft's new URL Rewriter? Your own proprietary solution?