Aspnetcore.docs: Will MVC's action automatic support "Preflight Requests"

Created on 25 Jun 2018  Â·  14Comments  Â·  Source: dotnet/AspNetCore.Docs

I'm wondering how MVC's EnableCORSAttribute support "OPTIONS" Request ?


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Source - Docs.ms doc-enhancement

Most helpful comment

Thanks for answering, but I didn't see one unique answer. There are many different opinions, also different solutions depending the configuration, and none of those works, at least in my case. I can't get it working. Also there is nothing in the Microsoft documentation, not for my setup. Another thread mentioned to install CORS extension in IIS, other to use filters in MVC (no effects). I could add again a middleware to filter the PREFETCH, but this doesn't seem a good solution. So I would like to have a official answer from Microsoft.

All 14 comments

@Rick-Anderson But which component handle it ? the app.UseCors() or [EnableCorsAttribute()]?
if I'm not use global cors (no app.UseCors()) and only do it in MVC action , Do I need write an additional action that has [HttpOptionsAttribute] ?

@HaoK should we add [EnableCors] to this doc? Can you comment on customer question?

Both UseCors() and MVC filter support the preflight request. However, CorsMiddleware does not work well with attribute-based routing, f.e. HttpPost, (see details in https://github.com/aspnet/Docs/issues/6447). I suggest you to use MVC filter.

For example:

        services.AddMvc(options =>
            {
                options.Filters.Add(new CorsAuthorizationFilterFactory("TrustedHosts"));
            });

Don't forget to send Origin and Access-Control-Request-Method headers while testing. Preflight requests are not handled for HttpGet actions.

Hi, my POST request with OPTIONS method in prefligh return 401 unauthorized. Get requests are working fine. Even POST works fine if sent without OPTIONS method. I am stuck due to ASP.Net core API CORS for my POST requests. Help needed badly!!
Thanks all.

CC @Rick-Anderson @HaoK

If I understand the customers original question correctly, I am here for the same reason.

Currently, the docs explain what pre-flight requests are here, but they do nothing to advise on _how_ someone is supposed to add support for wiring in OPTIONS request actions.

I think @dermeister0 touched on it a bit. Essentially, the developer is responsible for adding OPTIONS actions themselves because of things like route templates, which really sucks. I think this should be documented. Even better, it would be nice for some out of the box support for pre-flight requests.

For a more concrete example and to hopefully answer @John0King question you pretty much have to add this to every single controller:

/// <summary>
/// Returns an Allow HTTP header with the allowed HTTP methods.
/// </summary>
/// <returns>A 200 OK response.</returns>
[HttpOptions]
[SwaggerResponse(StatusCodes.Status200OK, "The allowed HTTP methods.")]
public IActionResult Options()
{
    this.HttpContext.Response.Headers.AppendCommaSeparatedValues(
        HeaderNames.Allow,
        HttpMethods.Get,
        HttpMethods.Head,
        HttpMethods.Options,
        HttpMethods.Post);
    return this.Ok();
}

/// <summary>
/// Returns an Allow HTTP header with the allowed HTTP methods for a car with the specified unique identifier.
/// </summary>
/// <param name="carId">The cars unique identifier.</param>
/// <returns>A 200 OK response.</returns>
[HttpOptions("{carId}")]
[SwaggerResponse(StatusCodes.Status200OK, "The allowed HTTP methods.")]
public IActionResult Options(int carId)
{
    this.HttpContext.Response.Headers.AppendCommaSeparatedValues(
        HeaderNames.Allow,
        HttpMethods.Delete,
        HttpMethods.Get,
        HttpMethods.Head,
        HttpMethods.Options,
        HttpMethods.Patch,
        HttpMethods.Post,
        HttpMethods.Put);
    return this.Ok();
}

See templates like these https://github.com/Dotnet-Boxed/Templates/blob/master/Source/Content/ApiTemplate/Controllers/CarsController.cs#L24-L64

I have a CRUD interface with 20ish entities, which means I have roughly 40 OPTIONS actions to handle.

@VictorioBerra
You don't need to create separate OPTIONS actions. Just add HttpOptions attribute to existing HttpPost or HttpPut method. Its body will not be executed during pre-flight request, but router will know that OPTIONS request should be processed.

Or simply use MVC filter instead of CORS middleware. It works fine.

@dermeister0

Just add HttpOptions attribute to existing HttpPost or HttpPut method. Its body will not be executed during pre-flight request, but router will know that OPTIONS request should be processed.

It won't work with AttributeRoute I think.

@John0King what do you mean?

You cant do [HttpOptions("/route")]?

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.2#attribute-routing-with-httpverb-attributes

@VictorioBerra Oh, I misunderstanding what @dermeister0 meant. Now I get it.
The wrong understanding is
```C#
[EnableCORS] // he said HttpOptionsAttribute,
[HttpPost("/api/post")]
public IActionResult PostAction()

And right understanding is

```C#
[EnableCORS]
[HttpPost("/api/post")]
[HttpOptions("/api/post")]
public IActionResult POSTAction()

@John0King what do you mean?

You cant do [HttpOptions("/route")]?

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.2#attribute-routing-with-httpverb-attributes

[HttpOptions] doesn't change anything. I think this doesn't work with attribute routing. Why isn't there an offical answer how to solve this problem?

Seems there are also issues when Windows Authentication is enabled on IIS.
So this is even more confusing.
My configuration:

  • Angular - ASP.NET Core 2.2 MVC WebApi
  • Angular xhr calls WithCredentials
  • IIS with Windows Authentication enabled, Anonymous disabled
  • Controllers and methods are using attributes
  • Cors is configured in Startup.cs

My question is, how to configure the server, that preflight calls (POST) get through?

Thanks for contacting us. We believe that the question you've raised have been answered. If you still feel a need to continue the discussion, feel free to reopen it and add your comments.

Thanks for answering, but I didn't see one unique answer. There are many different opinions, also different solutions depending the configuration, and none of those works, at least in my case. I can't get it working. Also there is nothing in the Microsoft documentation, not for my setup. Another thread mentioned to install CORS extension in IIS, other to use filters in MVC (no effects). I could add again a middleware to filter the PREFETCH, but this doesn't seem a good solution. So I would like to have a official answer from Microsoft.

I had the similar problem with my dot net core 2.0 Web API. All my POST requests were failing even i had set up the CORS correctly.
After my searches, I finally fixed it by using app.UseExceptionHandler(). Below is the implementation:

app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var errorFeature = context.Features.Get();
var exception = errorFeature.Error;

    context.Response.Headers.Add("Access-Control-Allow-Origin", "<Your Origin>");
    context.Response.StatusCode = StatusCodes.Status200OK;
    context.Response.WriteJson(problemDetails, "application/problem+json");

    await Task.CompletedTask;
});

});

Hope this helps !

Was this page helpful?
0 / 5 - 0 ratings