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

This article will demostrate 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 demostrate 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 everying 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, 
  1. // In general  
  2. services.AddCors(); 
with a Default policy,
  1. // Default Policy  
  2. services.AddCors(options =>  
  3. {  
  4.     options.AddDefaultPolicy(  
  5.         builder =>  
  6.         {  
  7.             builder.WithOrigins("https://localhost:44351""http://localhost:4200")  
  8.                                 .AllowAnyHeader()  
  9.                                 .AllowAnyMethod();  
  10.         });  
  11. }); 
or with a named policy,
  1. // Named Policy  
  2. services.AddCors(options =>  
  3. {  
  4.     options.AddPolicy(name: "AllowOrigin",  
  5.         builder =>  
  6.         {  
  7.             builder.WithOrigins("https://localhost:44351""http://localhost:4200")  
  8.                                 .AllowAnyHeader()  
  9.                                 .AllowAnyMethod();  
  10.         });  
  11. });  
Step 3 - Enable CORS in the Configure method of Startup.cs
 
You could enable CORS in Sonfigure method of Startup.cs as,
  1. // in general  
  2. app.UseCors(); 
define a policy,
  1. // Shows UseCors with CorsPolicyBuilder.  
  2. app.UseCors(builder =>  
  3. {  
  4.     builder  
  5.     .AllowAnyOrigin()  
  6.     .AllowAnyMethod()  
  7.     .AllowAnyHeader();  
  8. }); 
or with a named policy,
  1. // with a named pocili  
  2. 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.
  1. [EnableCors("AllowOrigin")]  
  2. // GET: api/StoresWebAPI  
  3. [HttpGet]  
  4. public async Task<ActionResult<IEnumerable<Store>>> GetStores()  
  5. {  
  6.     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
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     // In general  
  4.     services.AddCors();  
  5.  
  6.     ......
  7. }  
  8.    
  9. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  10. {  
  11.      ......     
  12.  
  13.     // Shows UseCors with CorsPolicyBuilder.  
  14.     app.UseCors(builder =>  
  15.     {  
  16.         builder  
  17.         .AllowAnyOrigin()  
  18.         .AllowAnyMethod()  
  19.         .AllowAnyHeader();  
  20.     });  
  21.   
  22.     ......
 Default Policy in ConfigureService Method: Working
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     // Default Policy  
  4.     services.AddCors(options =>  
  5.     {  
  6.         options.AddDefaultPolicy(  
  7.             builder =>  
  8.             {  
  9.                 builder.WithOrigins("https://localhost:44351""http://localhost:4200")  
  10.                                     .AllowAnyHeader()  
  11.                                     .AllowAnyMethod();  
  12.             });  
  13.     });  
  14.  
  15.    ......
  16. }  
  17.   
  18. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  19. {  
  20.      ......
  21.  
  22.     app.UseCors();  

  23.     ...... 

Named Policy in ConfigureService Method: Working
  1. public void ConfigureServices(IServiceCollection services)  
  2. {   
  3.     // Named Policy  
  4.     services.AddCors(options =>  
  5.     {  
  6.         options.AddPolicy(name: "AllowOrigin",  
  7.             builder =>  
  8.             {  
  9.                 builder.WithOrigins("https://localhost:44351""http://localhost:4200")  
  10.                                     .AllowAnyHeader()  
  11.                                     .AllowAnyMethod();  
  12.             });  
  13.     });  
  14.   
  15.  
  16.    ......
  17. }  
  18.   
  19. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  20. {  
  21.      ......
  22.  
  23.     app.UseCors();  

  24.     ...... 

  25. // Must Enable CORS from Action or Controller level
  26. [EnableCors("AllowOrigin")]  
  27. // GET: api/StoresWebAPI  
  28. [HttpGet]  
  29. public async Task<ActionResult<IEnumerable<Store>>> GetStores()  
  30. {  
  31.     return await _context.Stores.ToListAsync();  
  32. }
Combined Definitions of Policies: Working
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.  
  4.     // Default Policy  
  5.     services.AddCors(options =>  
  6.     {  
  7.         options.AddDefaultPolicy(  
  8.             builder =>  
  9.             {  
  10.                 builder.WithOrigins("https://localhost:44351""http://localhost:4200")  
  11.                                     .AllowAnyHeader()  
  12.                                     .AllowAnyMethod();  
  13.             });  
  14.     });  
  15.   
  16.     // Named Policy  
  17.     services.AddCors(options =>  
  18.     {  
  19.         options.AddPolicy(name: "AllowOrigin",  
  20.             builder =>  
  21.             {  
  22.                 builder.WithOrigins("https://localhost:44351""http://localhost:4200")  
  23.                                     .AllowAnyHeader()  
  24.                                     .AllowAnyMethod();  
  25.             });  
  26.     });  

  27.    ...... 
  28. }  
  29.   
  30. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  31. {  
  32.     ......
  33.  
  34.     app.UseCors();  
  35.   
  36.     // with a named pocili  
  37.     app.UseCors("AllowOrigin");  
  38.   
  39.     // Shows UseCors with CorsPolicyBuilder.  
  40.     app.UseCors(builder =>  
  41.     {  
  42.         builder  
  43.         .AllowAnyOrigin()  
  44.         .AllowAnyMethod()  
  45.         .AllowAnyHeader();  
  46.     });  
  47.   
  48.     ......

Without definition of a policy: Not Working
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     services.AddCors();  

  4.     ...... 
  5. }  
  6.   
  7. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  8. {  
  9.     ......     
  10.   
  11.     app.UseCors();  
  12.  
  13.    ......
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
  1. policy: Not Working  
  2.   
  3.     public void ConfigureServices(IServiceCollection services)    
  4.     {    
  5.           
  6.         ......   
  7.     }    
  8.         
  9.     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)    
  10.     {    
  11.         ......       
  12.         
  13.         app.UseCors();    
  14.        
  15.        ......  
  16.     }   
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