I've set up an ASP.NET web application starting with an MVC 4/Web API template. It seems as though things are working really well - no problems that I'm aware of. I've used Chrome and Firefox to go through the site. I've tested using Fiddler and all of the responses seem to be on the money.
So now I proceed to write a simple Test.aspx to consume this new Web API. The relevant parts of the script:
<script type="text/javascript"> $(function () { $.ajax({ url: "http://mywebapidomain.com/api/user", type: "GET", contentType: "json", success: function (data) { $.each(data, function (index, item) { .... }); } ); }, failure: function (result) { alert(result.d); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("An error occurred, please try again. " + textStatus); } }); }); </script>
This generates a REQUEST header:
OPTIONS http://host.mywebapidomain.com/api/user HTTP/1.1 Host: host.mywebapidomain.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Origin: http://mywebapidomain.com Access-Control-Request-Method: GET Access-Control-Request-Headers: content-type Connection: keep-alive
As is, Web API returns a 405 Method Not Allowed.
HTTP/1.1 405 Method Not Allowed Cache-Control: no-cache Pragma: no-cache Content-Type: application/xml; charset=utf-8 Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Mon, 30 Sep 2013 13:28:12 GMT Content-Length: 96 <Error><Message>The requested resource does not support http method 'OPTIONS'.</Message></Error>
I understand that the OPTIONS verb is not wired up in Web API controllers by default... So, I placed the following code in my UserController.cs:
// OPTIONS HTTP-verb handler public HttpResponseMessage OptionsUser() { var response = new HttpResponseMessage(); response.StatusCode = HttpStatusCode.OK; return response; }
...and this eliminated the 405 Method Not Allowed error, but the response is completely empty - no data is returned:
HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Mon, 30 Sep 2013 12:56:21 GMT Content-Length: 0
There must be additional logic... I don't know how to properly code the Options method or if the controller is even the proper place to put the code. Weird (to me) that the Web API site responds properly when viewed from Firefox or Chrome, yet the .ajax call above errors out. How do I handle the "preflight" check in the .ajax code? Maybe I should be addressing this issue on the client side's .ajax logic? Or, if this is an issue on the server side due to not handling the OPTIONS verb.
Can anyone help? This must be a very common issue and I apologize if it's been answered here. I searched but didn't find any answers that helped.
UPDATE IMHO, this is a client-side issue and has to do with the Ajax JQuery code above. I say this because Fiddler doesn't show any 405 error headers when I access mywebapidomain/api/user from a web browser. The only place I can duplicate this problem is from the JQuery .ajax() call. Also, the identical Ajax call above works fine when run on the server (same domain).
I found another post: Prototype AJAX request being sent as OPTIONS rather than GET; results in 501 error that seems to be related, but I've tinkered with their suggestions with no success. Apparently, JQuery is coded so that if an Ajax request is cross-domain (which mine is) it adds a couple of headers that trigger the OPTIONS header somehow.
'X-Requested-With': 'XMLHttpRequest', 'X-Prototype-Version': Prototype.Version,
It just seems that there should be a better solution available than modifying core code in JQuery...
The answer provided below assumes this is a server-side issue. Maybe, I guess, but I lean toward clients, and calling a hosting provider isn't going to help.
Mike Goodwin answer is great but it seemed, when I tried it, that it was aimed at MVC5/WebApi 2.1. The dependencies for Microsoft.AspNet.WebApi.Cors didn't play nicely with my MVC4 project.
The simplest way to enable CORS on WebApi with MVC4 was the following.
Note that I have allowed all, I suggest you limit the Origin's to just the clients you want your API to serve. Allowing everything is a security risk.
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD" /> <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> </customHeaders> </httpProtocol> </system.webServer>
We do this to allow the OPTIONS http verb
public class BaseApiController : ApiController { public HttpResponseMessage Options() { return new HttpResponseMessage { StatusCode = HttpStatusCode.OK }; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With