Enable CORS in ASP.NET Core API

Browsers do not allow cross origin communication for security reasons. This
means if an ASP.NET Core web API housed in one web app is called by JavaScript
code running as a part of another web app, the communication attempt will fail.
However, you can alter this default behavior by adding some configuration in
your API application. To that end this article discusses how that task can be
accomplished.
Note : If you are unfamiliar with CORS I suggest you go
here to familiarize with the basics.
In order to illustrate how CORS related configuration can be added to an API,
you need to create a new ASP.NET Core API project and an ASP.NET Core web
application project. The web app acts as a client to the API.
Now, go ahead and modify the API controller as shown below:
[Route("api/[controller]")]
[ApiController]
public class CountriesController : ControllerBase
{
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "USA", "UK", "India" };
}
}
Here, the CountriesController contains just the Get() action that returns a
list of countries. Run the API and confirm that countries are returned from the
Get() action as expected.

Now, open the client web app and write the following piece of jQuery code
inside the Index.cshtml. The jQuery code that calls the above API.
$(document).ready(function () {
var options = {};
options.url = "http://localhost:49313/
api/countries";
options.type = "GET";
options.dataType = "json";
options.success = function (countries) {
for (var i = 0; i < countries.length; i++) {
$("#response").append("<h2>" +
countries[i] + "</h2>");
console.log(countries[i]);
}
};
options.error = function (a, b, c) {
console.log(a);
console.log(b);
console.log(c);
};
$.ajax(options);
});
The above code uses jQuery Ajax to invoke the API. Notice that the URL
specified in the options points to the API residing in the another web
application (the API project). I won't go into the details of this code since
it's quite straightforward. It is suffice to say that the jQuery code invokes
the API using $.ajax() method and displays the returned countries in a <div>
element with ID of response.
At this stage your Solution Explorer should resemble this:

Next, run the API project followed by the client application. Try to hit
/Home/Index using the browser's address bar. You will find that nothing is shown
in the browser because of this error:

This error occurs because currently the API is not configured to deal with
CORS requests. Let's fix this issue by adding the required configuration.
Defining CORS policies
Go to the API project and open its Startup class. Add the following code in
the ConfigureServices() method.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
options.AddPolicy("MyCORSPolicy",
builder =>
{
builder.WithOrigins("http://localhost:49373")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddMvc().AddNewtonsoftJson();
}
The AddCors() method registers CORS to the services collection. Inside, we
define two CORS policies - default policy and a policy named MyCORSPolicy. This
is done using AddDefaultPolicy() and AddPolicy() methods respectively.
The default policy sets the default CORS configuration for the application.
In the above example, we specify that incoming request can belong to any origin,
it may use any HTTP verb, and any HTTP header. This is done using AllowAnyOrigin(),
AllowMethod(), and AllowAnyHeader() methods.
Then we create a custom policy called MyCORSPolicy. This policy allows only a
specific host (http://localhost:49373, make sure to change it as per your client
app's port) to invoke the API. Moreover, the policy specifies that any HTTP verb
can be used and also the HTTP headers.
There is a counterpart of AllowAnyXXXXXXX() methods. You will see a set of
WithXXXXXXX() methods that will allow you to configure specific hosts, methods,
and headers.
So far so good.
Using CORS policies
Now we will tell the framework to use our policies. To do so, go to the
Configure() method and write the following code in it:
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors("MyCORSPolicy");
app.UseRouting(routes =>
{
routes.MapApplication();
});
app.UseAuthorization();
}
The UseCors() method allows you to wire the policy into the middleware chain.
Here we specified that we want to use MyCORSPolicy defined earlier. If you wish
to use the default policy you would have said:
app.UseCors();
Ok. Now run the API and the client application. This time the client
application should be able to make a successful call to the API.

Enabling CORS for a specific action or controller
In the preceding example you enabled CORS at a global level so that all the
APIs in the project support CORS. However, at times you may want to enable CORS
at a narrow scope, say a particular action or controller. You can accomplish the
task using [EnableCors] attribute.
To use [EnableCors] attribute remove the UseCors() call from the Configure()
method. Then go to the Countries API and decorate the Get() action with [EnableCors]
as shown below:
[HttpGet]
[EnableCors("MyCORSPolicy")]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "USA", "UK", "India" };
}
In this case the [EnableCors] attribute specifies that we want to use
MyCORSPolicy policy defined earlier. If you would like to use the default policy
the usage would be:
[HttpGet]
[EnableCors]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "USA", "UK", "India" };
}
You can add [EnableCors] to individual actions or controller or page model
enable CORS to the underlying target. There is also counterpart of [EnableCors]
- the [DisableCors] attribute. The [DisableCors] attribute disables CORS support
for a particular action or controller.
You may read more details about enabling CORS in ASP.NET
here.
That's it for now! Keep coding!!