CORS (3), Enable CORS In .NET Core Web API

This is a series of articles to discuss CORS (Cross Origin Resource Sharing) issue for both setup and consumption.
This article will demonstrate how to enable CORS in .NET Core Web API for different situations.
 

Introduction

 
For this CORS article series, in Part I, we have made a separated Web API server and made an ASP.NET MVC Client to consume the Web API Server. In Part II, we made another Web API consumer, an Angular client, and show the effect of the CORS issue. In this article, we will demonstrate how to enable CORS in .NET Core Web API for different situations.
 

Requirements for Enabling CORS

 
To enable CORS in ASP.Net Core Web API, these are the steps we need to follow,
  1. Install the CORS middleware.
  2. Register CORS middleware to the pipeline in the ConfigureServices method of Startup.cs.
  3. Enable CORS in the Configure method of Startup.cs.
  4. Enable/Disable CORS in the controllers, the action methods, or globally.
Step 1 - Install the CORS middleware.
 
For .NET Core before v5.0, we need to install the Microsoft.AspNetCore.Cors Nuget package fromProject > Tools > NuGet Package Manager > Manage NuGet Packages for Solution.
 
However, for .NET Core 5.0, you do not need to do so, and if you skip this step, and everything will be OK for config CORS.
 
CORS package in NuGet
 
Step 2 - Register CORS middleware to the pipeline in the ConfigureServices method of Startup.cs.
 
You could register CORS in SonfigureService method of Startup.cs as, 
// In general  
services.AddCors(); 

with a Default policy,

// Default Policy  
services.AddCors(options =>  
{  
    options.AddDefaultPolicy(  
        builder =>  
        {  
            builder.WithOrigins("https://localhost:44351", "http://localhost:4200")  
                                .AllowAnyHeader()  
                                .AllowAnyMethod();  
        });  
}); 

or with a named policy,

// Named Policy  
services.AddCors(options =>  
{  
    options.AddPolicy(name: "AllowOrigin",  
        builder =>  
        {  
            builder.WithOrigins("https://localhost:44351", "http://localhost:4200")  
                                .AllowAnyHeader()  
                                .AllowAnyMethod();  
        });  
});  

Step 3 - Enable CORS in the Configure method of Startup.cs

You could enable CORS in Sonfigure method of Startup.cs as,
// in general  
app.UseCors(); 

Define a policy,

// Shows UseCors with CorsPolicyBuilder.  
app.UseCors(builder =>  
{  
    builder  
    .AllowAnyOrigin()  
    .AllowAnyMethod()  
    .AllowAnyHeader();  
}); 

or with a named policy,

// with a named pocili  
app.UseCors("AllowOrigin"); 

Note

  • You have to register the CORS in ConfigureService method, and enable CORS in Configure Method, and you could define the policy in both places. However:
  • You have to define the policy in at least one place;
  • The call to UseCors must be placed after UseRouting, but before UseAuthorization. For more information, see Middleware order, or the graph below here:
Step 4 - Enable/Disable CORS in the controllers, the action methods, or globally.
 
For default policy, it will automatically be global, while for named policies, you must use Enable CORS with attributes in Controller, Action level, like this; otherwise, it won't work.
  • [EnableCors] or [DisableCors] specifies the default policy.
  • [EnableCors("{Policy String}")] specifies a named policy.
    [EnableCors("AllowOrigin")]  
    // GET: api/StoresWebAPI  
    [HttpGet]  
    public async Task<ActionResult<IEnumerable<Store>>> GetStores()  
    {  
        return await _context.Stores.ToListAsync();  
    } 

     

Cases for Enabling CORS

 
Using the Web API server we developed in Part I, , and the Angular client we developed in Part II, we can make the tests below:
 
Define the policy in Configure Method: Working
public void ConfigureServices(IServiceCollection services)  
{  
    // In general  
    services.AddCors();  

    ......
}  
   
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
{  
     ......     

    // Shows UseCors with CorsPolicyBuilder.  
    app.UseCors(builder =>  
    {  
        builder  
        .AllowAnyOrigin()  
        .AllowAnyMethod()  
        .AllowAnyHeader();  
    });  
  
    ......
} 

Default Policy in ConfigureService Method: Working

public void ConfigureServices(IServiceCollection services)  
{  
    // Default Policy  
    services.AddCors(options =>  
    {  
        options.AddDefaultPolicy(  
            builder =>  
            {  
                builder.WithOrigins("https://localhost:44351", "http://localhost:4200")  
                                    .AllowAnyHeader()  
                                    .AllowAnyMethod();  
            });  
    });  

   ......
}  
  
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
{  
     ......

    app.UseCors();  

    ...... 
} 

Named Policy in ConfigureService Method: Working

public void ConfigureServices(IServiceCollection services)  
{   
    // Named Policy  
    services.AddCors(options =>  
    {  
        options.AddPolicy(name: "AllowOrigin",  
            builder =>  
            {  
                builder.WithOrigins("https://localhost:44351", "http://localhost:4200")  
                                    .AllowAnyHeader()  
                                    .AllowAnyMethod();  
            });  
    });  
  

   ......
}  
  
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
{  
     ......

    app.UseCors();  

    ...... 
} 

// Must Enable CORS from Action or Controller level
[EnableCors("AllowOrigin")]  
// GET: api/StoresWebAPI  
[HttpGet]  
public async Task<ActionResult<IEnumerable<Store>>> GetStores()  
{  
    return await _context.Stores.ToListAsync();  
}

Combined Definitions of Policies: Working

public void ConfigureServices(IServiceCollection services)  
{  

    // Default Policy  
    services.AddCors(options =>  
    {  
        options.AddDefaultPolicy(  
            builder =>  
            {  
                builder.WithOrigins("https://localhost:44351", "http://localhost:4200")  
                                    .AllowAnyHeader()  
                                    .AllowAnyMethod();  
            });  
    });  
  
    // Named Policy  
    services.AddCors(options =>  
    {  
        options.AddPolicy(name: "AllowOrigin",  
            builder =>  
            {  
                builder.WithOrigins("https://localhost:44351", "http://localhost:4200")  
                                    .AllowAnyHeader()  
                                    .AllowAnyMethod();  
            });  
    });  

   ...... 
}  
  
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
{  
    ......

    app.UseCors();  
  
    // with a named pocili  
    app.UseCors("AllowOrigin");  
  
    // Shows UseCors with CorsPolicyBuilder.  
    app.UseCors(builder =>  
    {  
        builder  
        .AllowAnyOrigin()  
        .AllowAnyMethod()  
        .AllowAnyHeader();  
    });  
  
    ......
} 

Without definition of a policy: Not Working

public void ConfigureServices(IServiceCollection services)  
{  
    services.AddCors();  

    ...... 
}  
  
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
{  
    ......     
  
    app.UseCors();  

   ......
} 

Note
Here, we use angular client developed in Part II to do our tests, but not the MVC client we devbeloped in Part I. Actually, by my test, the MVC Client is automatically to have access to Web API different origin source, that we only need to enable CORS from Config method like below,

 For .NET Core MVC Client, it is working
policy: Not Working  
  
    public void ConfigureServices(IServiceCollection services)    
    {    
          
        ......   
    }    
        
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)    
    {    
        ......       
        
        app.UseCors();    
       
       ......  
    }   

I do not know the reason, and I cannot get any explanation from online.  Anyone has knowledge about that, I will appreciate your input.

 

Summary

 
As a conclusion of this CORS article-series (with Part I, Part II), we discuss the methods to enable CORS in .NET Core Web API for different situations.
  
Note
One more method to enable CORS we did not cover is Enable Cors with endpoint routing, see details 《Enable Cross-Origin Requests (CORS) in ASP.NET Core》.
 
References