Handling CORS Preflight requests to ASP.NET MVC actions

So I have found a solution that works. For each request, I check whether it's a CORS request & whether the request is coming in with the OPTIONS verb, indicating that it's the preflight request. If it is, I just send an empty response back (which only contains the headers configured in IIS of course), thus negating the controller action execution.

Then if the client confirms it's allowed to perform the request based on the returned headers from preflight, the actual POST is performed & the controller action is executed. And example of my code:

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OrdinalIgnoreCase) &&
        Request.HttpMethod == "OPTIONS") {
        Response.Flush();
    }
}

As mentioned, this worked for me, but if anyone knows of a better way, or of any flaws in my current implementation, I would appreciate to hear about them.


expanding on Carl's answer, i took his code and plugged it into my OWIN pipeline:

app.Use((context, next) =>
{
     if (context.Request.Headers.Any(k => k.Key.Contains("Origin")) && context.Request.Method == "OPTIONS")
     {
         context.Response.StatusCode = 200;
         return context.Response.WriteAsync("handled");
     }

     return next.Invoke();
});

Just add this to the beginning (or anywhere before you register the WebAPI) of your IAppBuilder in Startup.cs


The accepted answer works like a charm, but I found that the request was actually being passed down to the controller. I was receiving a 200 status code, but the response body contained a lot of HTML with an exception from the controller. So instead of using Response.Flush(), I found it was better to use Response.End(), which does stop the execution of the request. This alternative solution would look like this:

EDIT: fixed a typo carried from the original answer.

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OrdinalIgnoreCase) &&
        Request.HttpMethod == "OPTIONS") {
        Response.End();
    }
}