I have an ASP.NET Web API application running on my local instance of IIS. The web application is configured with CORS. The Web API method I am calling reads something like:
[POST("/API/{foo}/{bar}")]
public String DoSomething(String foo, String bar)
{
return "Hello, World!";
}
Client side, I’m running the following request:
$.ajax({
url: "http://machine/API/Foo/Bar",
type: "POST",
success: function (data) {
console.log("Success: " + data);
},
error: function (xhr, status, message) {
console.log("Failure: " + status + ", " + message);
}
});
The corresponding console log within Firefox 15.0.1 reads as:
test.html (line 38)
POST http://machine/API/Foo/Bar
200 OK
112ms
jquery-1.7.2.js (line 8240)
Success: "Hello, World!"
This works flawlessly when I’m accessing my local IIS server as well as when I have it accessing the corresponding URL for the IIS Express development instance within Visual Studio.
When I add a single request header, anything at all, the following request fails when made against my local IIS server:
$.ajax({
url: "http://machine/API/Foo/Bar",
type: "POST",
onBeforeSend: function (xhr, settings) {
xhr.setRequestHeader("A", "B");
},
success: function (data) {
console.log("Success: " + data);
},
error: function (xhr, status, message) {
console.log("Failure: " + status + ", " + message);
}
});
The ever so verbose log message I see is:
Failure: error,
The same POST request is successful when made against the IIS Express development instance within Visual Studio.
In Fiddler, the previous two requests go through without failure regardless of whether I’m targeting the full IIS server or IIS Express within Visual Studio:
// Request
POST http://machine/Foo/Bar HTTP/1.1
Host: machine
Content-Length: 0
// Response
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 38
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 09 Oct 2012 20:16:29 GMT
"Hello, World!"
The permutations {With Headers, Without Headers} x {Full IIS, IIS Express} all produce identical output within Fiddler.
In short: Why does having request headers set cause the AJAX call to fail against my local fully fledged IIS instance?
Furthermore, why does my requests succeed in Fiddler but not in my Javascript code? This is a serious deal breaker if I can’t set request headers in a proper IIS instance.
The actual underlying issue with my CORS problem was related to the pipeline utilized by IIS 7.
When IIS 7 is operating under the Classic Pipeline, requests were not being preflighted with the
OPTIONSrequest. They would fail silently as I described in my question. I saw this in the Net tab of Firebug and via interactive debugging with the Thinktecture IdentityModel library explicitly included as a project to my solution.But when IIS 7 operates under Integrated Pipeline, CORS is respected.
POSTrequests and requests with custom headers are correctly preflighted.