Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Core 2.0 - Still seeing No 'Access-Control-Allow-Origin' header error

I'm at wit's end on this one. I've already researched other answers to similar questions on SO w/o any luck.

I'm fairly certain I've got CORS enabled correctly to allow incoming requests (in this case, POST requests) from all origins, but I'm seeing the error below:

Failed to load http://localhost:5000/expenses: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 500.

Here's how I've enabled CORS in my webAPI project:

relevant methods in Startup.cs

 // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors();
            services.AddMvc();

            services.AddDbContext<ExpensesDbContext>(options =>
                                                    options.UseMySQL(Configuration.GetConnectionString("DefaultConnection")));
            services.AddTransient<IBaseDa<Accounts>, AccountsDataAccess>();
            services.AddTransient<IExpensesDa, ExpensesDa>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            env.EnvironmentName = "Development";

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors(builder => builder
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowAnyOrigin()
                        .AllowCredentials());

            app.UseMvc();
        }

If i'm using .AllowAnyOrigin() and .AllowAnyMethod(), why am I seeing the error above?

like image 761
Steve Boniface Avatar asked Jun 19 '18 00:06

Steve Boniface


People also ask

How do I fix no Access-Control allow origin?

If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.

How do I enable CORS in net core?

There are three ways to enable CORS: In middleware using a named policy or default policy. Using endpoint routing. With the [EnableCors] attribute.


2 Answers

Was scratching my head on this situation here for a while. I had CORS enabled properly, but some calls were still returning the Access-Control-Allow-Origin error. I found problem... the sneaky sneaky problem...

Our problem caused by how we were using app.UseExceptionHandler. Specifically, here's the code we were using, except our original code didn't have the context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); line.

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

        var problemDetails = new ProblemDetails
        {
            Title = R.ErrorUnexpected,
            Status = status,
            Detail =
              $"{exception.Message} {exception.InnerException?.Message}"
        };

        context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        context.Response.StatusCode = problemDetails.Status.GetValueOrDefault();
        context.Response.WriteJson(problemDetails, "application/problem+json");

        await Task.CompletedTask;
    });
});

app.UseExceptionHandler is a much lower level function than controller actions, and thus do not take part in anything related to CORS natively. Adding context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); fixed the problem.

like image 110
Alex Dresko Avatar answered Oct 23 '22 08:10

Alex Dresko


The combination of netCore2.0 (http://localhost:5000/) + Angular (http://localhost:4200) + chrome = Access-Control-Allow-Origin. I have had this issue before and it took me 3 days to realize that chrome will always throw this error. I think it is because chrome views localhost as the origin disregarding the port even tho the middleware explicitly tells it not too especially on POST requests.

I would try and define a policy in your startup.cs Configure services:

  public void ConfigureServices(IServiceCollection services)
        {
  //add cors service
            services.AddCors(options => options.AddPolicy("Cors",
                builder =>
                {
                    builder.AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
                }));

then in your Configure method I would add that:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //authentication added 
            app.UseAuthentication();

            app.UseCors("Cors");
            app.UseMvc();
        }

... This most likely wont work and but try it any who.... This drove me mad and I needed the satisfaction of seeing if the request even attempted to hit the asp.netCore backend: I used

If you really want to see I would clear your cache and cookies then add IHttpContextAccessor to get low level control of whats going on in the request. In my dilema with the same problem I needed angular to send an image. I was getting the annyoing Origin error then through exprimenting I got the Image by injecting IHttpContextAccessor into my controller and

debugging

public void ConfigureServices(IServiceCollection services)
{
  //add cors service
                services.AddCors(options => options.AddPolicy("Cors",
                    builder =>
                    {
                        builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader();
                    }));

    services.AddMvc();

         // register an IHttpContextAccessor so we can access the current
            // HttpContext in services by injecting it
            //---we use to this pull out the contents of the request

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

you want to inject this into whatever controller u are

using to retrieve the json object of the POST request. Im going to use the example as Home controller:

public class HomeController : Controller
    {

        // make a read only field
        private readonly IHttpContextAccessor _httpContextAccessor;

    //create ctor for controller and inject it
    public UserService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    // now in your post method use this to see what the if anything came in through the request:
    public async Task<IActionResult> Picload(IFormFile file){//---always null

    // in my problem I was loading and image from.
    var file =  _httpContextAccessor.HttpContext.Request.Form.Files[0];
}

Using this it gave me access to the image chrome was giving me an Origin error about.

like image 43
Mohamoud Mohamed Avatar answered Oct 23 '22 10:10

Mohamoud Mohamed