3

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!

Drew Green
  • 51
  • 1
  • 4
  • this link may help you: http://stackoverflow.com/questions/7001846/how-to-handle-options-method-in-asp-net-mvc. It seems to me that you have to allow OPTIONS verb on the server side. Try adding OPTIONS to header "Access-Control-Allow-Methods" like in the answer. – myroman Jul 16 '15 at 17:20

1 Answers1

3
protected void Application_BeginRequest()
{

    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();
    }

}

The code above mentioned worked for me

Rohit Poudel
  • 1,793
  • 2
  • 20
  • 24
Speero
  • 31
  • 4
  • But that is almost exactly what OP says they already did which is working. This answers nothing. – Heki Jul 06 '20 at 08:44