I've been having a CORS configuration issue for over an hour now and I can't find a question that helps me understand this situation.
I have an XHR firing on a staging domain with a preflight OPTIONS
request that is returning with a 400, and the POST is not being sent because the CORS header to permit it isn't present.
I have config.EnableCors();
in my WebApiConfig.cs
and am using the NuGet package Microsoft ASP.NET Web API 2.2 Cross-Origin Support
(Microsoft.AspNet.WebApi.Cors v5.23)
I then set a default instead of using the empty constructor, having seen this question so the WebApiConfig
lines are:
var defaultCors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(defaultCors);
I don't mind this but I'd prefer not setting anything here at all. In any case, this isn't working.
The errors look like this when the OPTIONS
request is handled by the Global.asax.cs
but doesn't write the header:
OPTIONS http://staging.example.com:8044/Controller/Action
XMLHttpRequest cannot load http://staging.example.com:8044/Controller/Action. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://staging.example.co.uk:8044' is therefore not allowed access.
The error looks like this when the request isn't handled in the Global.asax.cs
:
OPTIONS http://staging.example.com:8044
XMLHttpRequest cannot load http://staging.example.com:8044/Controller/Action. Invalid HTTP status code 400
I have been able to access the API cross-domain by using this solution in the Global.asax.cs
:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://staging.example.com:8044");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Accepts, Content-Type, Origin, X-My-Header");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "60");
HttpContext.Current.Response.End();
}
}
}
What I actually want to be doing is this:
[EnableCors("http://www.example.com", "*", "get,post")]
public sealed class ControllerController : ApiController
{
[EnableCors("http://staging.example.com:8044,http://www.example.com", "*", "post")]
[HttpPost]
public async Task<HttpResponseMessage> Action([FromBody] ModelledInput input)
{
...
}
}
I can't understand why the CORS attribute isn't handling the preflight request, though I understand why the BeginRequest
is. I want the CORS control to be managed on a controller or action level, not globally. I thought it might be the HttpPost
attribute but removing that didn't work.
I'm open to the suggestion I have done something wrong or that the request may be being filtered or handled higher up - I'm not certain where to look to address this but I'm not happy to handle CORS globally.
I'd appreciate any help!