In this post, we will focus on how to enable CORS in ASP.Net Core application, get knowledge about CORS policy, and how we can share resources through different origins.
The following topics will be discussed.
- What is CORS?
- Create .NET Core WebAPI Application
- Add Packages
- Add Database Connection
- Enable CORS
- Publishing to IIS
- Share Through .NET Core Sample Application
Introduction
First, let’s get introduced to CORS. According to Wikipedia, "Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the resource originated."
Get more details from docs.asp.net. Let’s get started with a sample application.
Create New Application
Open Visual Studio 2015, then go top menu. and Click > File > New > Project

Choose Web API template.

Finally, .Net Core Welcome page will appear. Read more about .NET Core.

First, we need to add required packages to the sample application. Here, we have added those packages listed below in project.json file. After putting all those packages in our project config file, they will automatically be added to our application by IDE.
project.json
- //EntityFrameworkCore
- "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
- "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
- "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1",
- "Microsoft.EntityFrameworkCore": "1.0.1",
- //Cross Origin Resource Sharing
- "Microsoft.AspNetCore.Cors": "1.0.0"
appsettings.json
- {
- "ConnectionStrings": {
- "dbConn": "Server=DESKTOP-JAKRV2S;Database=PhoneBook;Trusted_Connection=True;MultipleActiveResultSets=true"
- },
- "Logging": {
- "IncludeScopes": false,
- "LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
- }
- }
- }
- publicvoidConfigureServices(IServiceCollection services) {
- //Add database services.
- varconnectionString = this.Configuration.GetConnectionString("dbConn");
- services.AddDbContext < PhoneBookContext > (options => options.UseSqlServer(connectionString));
- // Add framework services.
- services.AddApplicationInsightsTelemetry(Configuration);
- services.AddMvc();
- }
Here, we have also specified different CORS enabled policies by using CorsPolicyBuilder. You may test by enabling different types with this sample application.
Startup.cs ConfigureServices
- services.AddCors(
- options => options.AddPolicy("AllowCors",
- builder => {
- builder
- //.WithOrigins("http://localhost:4456") //AllowSpecificOrigins;
- //.WithOrigins("http://localhost:4456", "http://localhost:4457") //AllowMultipleOrigins;
- .AllowAnyOrigin() //AllowAllOrigins;
- //.WithMethods("GET") //AllowSpecificMethods;
- //.WithMethods("GET", "PUT") //AllowSpecificMethods;
- //.WithMethods("GET", "PUT", "POST") //AllowSpecificMethods;
- .WithMethods("GET", "PUT", "POST", "DELETE") //AllowSpecificMethods;
- //.AllowAnyMethod() //AllowAllMethods;
- //.WithHeaders("Accept", "Content-type", "Origin", "X-Custom-Header"); //AllowSpecificHeaders;
- .AllowAnyHeader(); //AllowAllHeaders;
- })
- );
With Origin
- Allow Specific Origin
builder.WithOrigins("http://localhost:4456")
- Allow Multiple Origins
builder.WithOrigins("http://localhost:4456", "http://localhost:4457")
- Allow All Origins
builder.AllowAnyOrigin()
With Methods
- Allow Specific Methods
builder.WithMethods("GET", "PUT", "POST", "DELETE")
- Allow All Methods
builder.AllowAnyMethod()
With Headers
- Allow Specific Headers
builder.WithHeaders("Accept", "Content-type", "Origin", "X-Custom-Header")
- Allow All Headers
builder.AllowAnyHeader()
After that, we have enabled CORS for your application, using an extension method “UseCors“.
Startup.cs Configure- //Enable CORS policy "AllowCors"
- app.UseCors("AllowCors");
- publicclassStartup {
- public Startup(IHostingEnvironmentenv) {
- var builder = newConfigurationBuilder()
- .SetBasePath(env.ContentRootPath)
- .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
- .AddJsonFile($ "appsettings.{env.EnvironmentName}.json", optional: true);
- if (env.IsEnvironment("Development")) {
- // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
- builder.AddApplicationInsightsSettings(developerMode: true);
- }
- builder.AddEnvironmentVariables();
- Configuration = builder.Build();
- }
- publicIConfigurationRoot Configuration {
- get;
- }
- // This method gets called by the runtime. Use this method to add services to the container
- publicvoidConfigureServices(IServiceCollection services) {
- //Add database services.
- varconnectionString = this.Configuration.GetConnectionString("dbConn");
- services.AddDbContext < PhoneBookContext > (options => options.UseSqlServer(connectionString));
- // Add framework services.
- services.AddApplicationInsightsTelemetry(Configuration);
- services.AddMvc();
- //Add CORS services.
- //services.Configure<MvcOptions>(options =>
- //{
- // options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
- //});
- services.AddCors(
- options => options.AddPolicy("AllowCors",
- builder => {
- builder
- //.WithOrigins("http://localhost:4456") //AllowSpecificOrigins;
- //.WithOrigins("http://localhost:4456", "http://localhost:4457") //AllowMultipleOrigins;
- .AllowAnyOrigin() //AllowAllOrigins;
- //.WithMethods("GET") //AllowSpecificMethods;
- //.WithMethods("GET", "PUT") //AllowSpecificMethods;
- //.WithMethods("GET", "PUT", "POST") //AllowSpecificMethods;
- .WithMethods("GET", "PUT", "POST", "DELETE") //AllowSpecificMethods;
- //.AllowAnyMethod() //AllowAllMethods;
- //.WithHeaders("Accept", "Content-type", "Origin", "X-Custom-Header"); //AllowSpecificHeaders;
- .AllowAnyHeader(); //AllowAllHeaders;
- })
- );
- }
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
- publicvoid Configure(IApplicationBuilder app, IHostingEnvironmentenv, ILoggerFactoryloggerFactory) {
- loggerFactory.AddConsole(Configuration.GetSection("Logging"));
- loggerFactory.AddDebug();
- app.UseApplicationInsightsRequestTelemetry();
- app.UseApplicationInsightsExceptionTelemetry();
- app.UseMvc();
- //Enable CORS policy "AllowCors"
- app.UseCors("AllowCors");
- }
- }
Here is the list of required namespaces.
- usingMicrosoft.AspNetCore.Mvc;
- usingMicrosoft.AspNetCore.Cors;
- usingCrossOrigin.WebService.Models.DbEntities;
- usingMicrosoft.EntityFrameworkCore;
Here, we are applying specific CORS policies on APiController. It can also be applied on a per action basis, or globally, for all controllers.
- [EnableCors("AllowCors"), Route("api/[controller]")]
- publicclassContactController: Controller {
- privatePhoneBookContext _ctx = null;
- publicContactController(PhoneBookContext context) {
- _ctx = context;
- }
- // GET: api/Contact/GetContact
- [HttpGet("GetContact"), Produces("application/json")]
- publicasyncTask < object > GetContact() {
- List < Contacts > contacts = null;
- object result = null;
- try {
- using(_ctx) {
- contacts = await _ctx.Contacts.ToListAsync();
- result = new {
- contacts
- };
- }
- } catch (Exception ex) {
- ex.ToString();
- }
- return contacts;
- }
- // GET api/Contact/GetContactByID/5
- [HttpGet("GetContactByID/{id}"), Produces("application/json")]
- publicasyncTask < Contacts > GetContactByID(int id) {
- Contacts contact = null;
- try {
- using(_ctx) {
- contact = await _ctx.Contacts.FirstOrDefaultAsync(x => x.ContactId == id);
- }
- } catch (Exception ex) {
- ex.ToString();
- }
- return contact;
- }
- // POST api/Contact/PostContact
- [HttpPost, Route("PostContact"), Produces("application/json")]
- publicasyncTask < object > PostContact([FromBody] Contacts model) {
- object result = null;
- string message = "";
- if (model == null) {
- returnBadRequest();
- }
- using(_ctx) {
- using(var _ctxTransaction = _ctx.Database.BeginTransaction()) {
- try {
- _ctx.Contacts.Add(model);
- await _ctx.SaveChangesAsync();
- _ctxTransaction.Commit();
- message = "Saved Successfully";
- } catch (Exception e) {
- _ctxTransaction.Rollback();
- e.ToString();
- message = "Saved Error";
- }
- result = new {
- message
- };
- }
- }
- return result;
- }
- // PUT api/Contact/PutContact/5
- [DisableCors, HttpPut, Route("PutContact/{id}")]
- publicasyncTask < object > PutContact(int id, [FromBody] Contacts model) {
- object result = null;
- string message = "";
- if (model == null) {
- returnBadRequest();
- }
- using(_ctx) {
- using(var _ctxTransaction = _ctx.Database.BeginTransaction()) {
- try {
- varentityUpdate = _ctx.Contacts.FirstOrDefault(x => x.ContactId == id);
- if (entityUpdate != null) {
- entityUpdate.FirstName = model.FirstName;
- entityUpdate.LastName = model.LastName;
- entityUpdate.Phone = model.Phone;
- entityUpdate.Email = model.Email;
- await _ctx.SaveChangesAsync();
- }
- _ctxTransaction.Commit();
- message = "Entry Updated";
- } catch (Exception e) {
- _ctxTransaction.Rollback();
- e.ToString();
- message = "Entry Update Failed!!";
- }
- result = new {
- message
- };
- }
- }
- return result;
- }
- // DELETE api/Contact/DeleteContactByID/5
- [HttpDelete, Route("DeleteContactByID/{id}")]
- publicasyncTask < object > DeleteContactByID(int id) {
- object result = null;
- string message = "";
- using(_ctx) {
- using(var _ctxTransaction = _ctx.Database.BeginTransaction()) {
- try {
- varidToRemove = _ctx.Contacts.SingleOrDefault(x => x.ContactId == id);
- if (idToRemove != null) {
- _ctx.Contacts.Remove(idToRemove);
- await _ctx.SaveChangesAsync();
- }
- _ctxTransaction.Commit();
- message = "Deleted Successfully";
- } catch (Exception e) {
- _ctxTransaction.Rollback();
- e.ToString();
- message = "Error on Deleting!!";
- }
- result = new {
- message
- };
- }
- }
- return result;
- }
- }
Publishing to IIS
We need to prepare our Server for ASP.NET Core application to host. Get more details on Publishing .NET Core Application. We have used localhost with assigning port 8081, to get accessed by our Sharing application.
http://localhost:8081

Let’s browse our application by using http://localhost:8081 URL, as you can see our API is working with response of JSON data.

Now is the time to access the shared resource. I have added an existing sample application to this solution. Given below is the simple change that I have made to access the resource via API from different origin.
Share Resource
Here, we have tried to access the resource through http://localhost:8081 but a server error occurred, as you can see below.
After enabling CORS we have successfully been able to access the shared resource through Web API.

Output

Source Code
I’ve uploaded the full source code to download/clone @github. Hope this will help.

Bryian TanPosted Aug 16, 2017, 12:04 AM
Good stuff. Thanks.
Prasanna MuraliPosted Oct 28, 2016, 8:14 AM
Nice post...