MVC web api: No 'Access-Control-Allow-Origin' header is present on the requested resource

C#asp.net MvcAngularjsasp.net Web-ApiCors

C# Problem Overview


I tried everything that is written in this article: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api, but nothing works. I'm trying to get data from webAPI2 (MVC5) to use in another domain using angularJS.

my controller looks like this:

namespace tapuzWebAPI.Controllers
{
    [EnableCors(origins: "http://local.tapuz.co.il", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/homepage")]
    public class HomePageController : ApiController
    {
        [HttpGet]
        [Route("GetMainItems")]
        //[ResponseType(typeof(Product))]
        public List<usp_MobileSelectTopSecondaryItemsByCategoryResult> GetMainItems()
        {
          

            HomePageDALcs dal = new HomePageDALcs();
            //Three product added to display the data

            //HomePagePromotedItems.Value.Add(new HomePagePromotedItem.Value.FirstOrDefault((p) => p.ID == id));


            List<usp_MobileSelectTopSecondaryItemsByCategoryResult> items = dal.MobileSelectTopSecondaryItemsByCategory(3, 5);
            return items;

        }      
    }
}

C# Solutions


Solution 1 - C#

You need to enable CORS in your Web Api. The easier and preferred way to enable CORS globally is to add the following into web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Please note that the Methods are all individually specified, instead of using *. This is because there is a bug occurring when using *.

You can also enable CORS by code.

Update
The following NuGet package is required: Microsoft.AspNet.WebApi.Cors.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();
        
        // ...
    }
}

Then you can use the [EnableCors] attribute on Actions or Controllers like this

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]

Or you can register it globally

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("http://www.example.com", "*", "*");
        config.EnableCors(cors);
        
        // ...
    }
}

You also need to handle the preflight Options requests with HTTP OPTIONS requests.

Web API needs to respond to the Options request in order to confirm that it is indeed configured to support CORS.

To handle this, all you need to do is send an empty response back. You can do this inside your actions, or you can do it globally like this:

# Global.asax.cs
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

This extra check was added to ensure that old APIs that were designed to accept only GET and POST requests will not be exploited. Imagine sending a DELETE request to an API designed when this verb didn't exist. The outcome is unpredictable and the results might be dangerous.

Solution 2 - C#

@Mihai-Andrei Dinculescu's answer is correct, but for the benefit of searchers, there is also a subtle point that can cause this error.

Adding a '/' on the end of your URL will stop EnableCors from working in all instances (e.g. from the homepage).

I.e. This will not work

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net/", "*", "*");
config.EnableCors(cors);

but this will work:

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net", "*", "*");
config.EnableCors(cors);

The effect is the same if using the EnableCors Attribute.

Solution 3 - C#

I followed all the steps above indicated by Mihai-Andrei Dinculescu.
But in my case, I needed 1 more step because http OPTIONS was disabled in the Web.Config by the line below.

<remove name="OPTIONSVerbHandler" />

I just removed it from Web.Config (just comment it like below) and Cors works like a charm

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>

Solution 4 - C#

It may be because of the installation of Cors nuget packages.

If you facing the problem after installing and enabaling cors from nuget , then you may try reinstalling web Api.

From the package manager, run Update-Package Microsoft.AspNet.WebApi -reinstall

Solution 5 - C#

Try this, to make sure you configured CORS correctly:

[EnableCors(origins: "*", headers: "*", methods: "*")]

Still not working? Check HTTP headers presence.

Solution 6 - C#

I know I'm coming to this very late. However, for anyone who's searching, I thought I'd publish what FINALLY worked for me. I'm not claiming it's the best solution - only that it worked.

Our WebApi service uses the config.EnableCors(corsAttribute) method. However, even with that, it would still fail on the pre-flight requests. @Mihai-Andrei Dinculescu's answer provided the clue for me. First of all, I added his Application_BeginRequest() code to flush the options requests. That STILL didn't work for me. The issue is that WebAPI still wasn't adding any of the expected headers to the OPTIONS request. Flushing it alone didn't work - but it gave me an idea. I added the custom headers that would otherwise be added via the web.config to the response for the OPTIONS request. Here's my code:

protected void Application_BeginRequest()
{
  if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
  {
    Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:44343");
    Response.Headers.Add("Access-Control-Allow-Headers",
      "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    Response.Flush();
  }
}

Obviously, this only applies to the OPTIONS requests. All other verbs are handled by the CORS configuration. If there's a better approach to this, I'm all ears. It feels like a cheat to me and I would prefer if the headers were added automatically, but this is what finally worked and allowed me to move on.

Solution 7 - C#

To make any CORS protocol to work, you need to have a OPTIONS method on every endpoint (or a global filter with this method) that will return those headers :

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

The reason is that the browser will send first an OPTIONS request to 'test' your server and see the authorizations

Solution 8 - C#

I catch the next case about cors. Maybe it will be useful to somebody. If you add feature 'WebDav Redirector' to your server, PUT and DELETE requests are failed.

So, you will need to remove 'WebDAVModule' from your IIS server:

  • "In the IIS modules Configuration, loop up the WebDAVModule, if your web server has it, then remove it".

Or add to your config:

<system.webServer>
<modules>
  <remove name="WebDAVModule"/>
</modules>
<handlers>
  <remove name="WebDAV" />
  ...
</handlers>

Solution 9 - C#

That problem happens when you try to access from a different domain or different port.

If you're using Visual Studio, then go to Tools > NuGet Package Manager > Package Manager Console. There you have to install the NuGet Package Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

Then, in PROJECT > App_Start > WebApiConfig, enable CORS

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        
        //Enable CORS. Note that the domain doesn't have / in the end.
        config.EnableCors(new EnableCorsAttribute("https://tiagoperes.eu",headers:"*",methods:"*"));

        ....

    }
}

Once installed successfully, build the solution and that should suffice

Solution 10 - C#

@Mihai-Andrei Dinculescu's answer worked for me, e.g.:

  • Adding a <httpProtocol>in the web.config's <system.webServer> section
  • Returning empty response for OPTIONS requests via the mentioned Application_BeginRequest() in global.asax

Except that his check for Request.Headers.AllKeys.Contains("Origin") did NOT work for me, because the request contained an origing, so with lowercase. I think my browser (Chrome) sends it like this for CORS requests.

I solved this a bit more generically by using a case insensitive variant of his Contains check instead:

if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {

Solution 11 - C#

If you have security\requestFiltering nodes in your web.config as follows:

<security>
  <requestFiltering>
    <verbs allowUnlisted="false">
      <add verb="GET" allowed="true" />
      <add verb="POST" allowed="true" />
      <add verb="PUT" allowed="true" />
      <add verb="DELETE" allowed="true" />
      <add verb="DEBUG" allowed="true" />          
    </verbs>
  </requestFiltering>

make sure you add this as well

<add verb="OPTIONS" allowed="true" />

Solution 12 - C#

I had tried everything I could find on the net including the methods that have been given on this answer. After almost trying to solve the problem for whole day I have found the solution that have worked for me like a charm.

in the file WebApiConfig in folder App_Start, comment all the lines of code and add the following code:

`public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();
        var enableCorsAttribute = new EnableCorsAttribute("*",
                                           "Origin, Content-Type, Accept",
                                           "GET, PUT, POST, DELETE, OPTIONS");
        config.EnableCors(enableCorsAttribute);
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            //routeTemplate: "api/{controller}/{id}",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        config.Formatters.Add(new BrowserJsonFormatter());
    }

    public class BrowserJsonFormatter : JsonMediaTypeFormatter
    {
        public BrowserJsonFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            this.SerializerSettings.Formatting = Formatting.Indented;
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }`

Solution 13 - C#

I know that people will probably find this very obvious at first, but really think about this. This can often happen if you've done something wrong.

For instance, I've had this problem because I didn't add a host entry to my hosts file. The real problem was DNS resolution. Or I just got the base URL wrong.

Sometimes I get this error if the identity token came from one server, but I'm trying to use it on another.

Sometimes you'll get this error if you've got the resource wrong.

You might get this if you put the CORS middleware too late in the chain.

Solution 14 - C#

Avoid multiple place enabling CORS,Like WebApiCOnfig.cs, GrantResourceOwnerCredentials method in provider and Controller Header attribute etc. Below are the list which also cause the Access Control Allow Origin

  1. Web having truble in interacting with DB which you used.
  2. AWS Cloud If VPC of Web API and DB are different.

Below code is more then enough to fix the access control allow origin. //Make sure app.UseCors should be top of the code line of configuration.

   public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            //All other configurations
        }
    }

This slowed my problem.

Solution 15 - C#

Install package : Microsoft.AspNet.WebApi.Cors

go to : App_Start --> WebApiConfig

Add :

var cors = new EnableCorsAttribute("http://localhost:4200";, "", ""); config.EnableCors(cors);

Note : If you add '/' as end of the particular url not worked for me.

Solution 16 - C#

For people that are simply creating a Web API in .NET 5 and not a Web App, in Startup.cs you'll need to configure your policy like so:

public void ConfigureServices(IServiceCollection services)
{
    // Additional configs above...
    services.AddCors(options =>
    {
        options.AddPolicy("AllowAnyOrigin", builder =>
        {
            // Allow "Access-Control-Allow-Origin: *" header
            builder.AllowAnyOrigin();
        });
    });
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Add this above other config options...
    app.UseCors("AllowAnyOrigin");
}

Solution 17 - C#

I know this sounds crazy but for me it was [HttpPost()] instead of [HttpPost]. When I removed the redundant parentheses, it started working

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNoa GaniView Question on Stackoverflow
Solution 1 - C#Mihai DinculescuView Answer on Stackoverflow
Solution 2 - C#JsAndDotNetView Answer on Stackoverflow
Solution 3 - C#AlbertSYView Answer on Stackoverflow
Solution 4 - C#Bimal DasView Answer on Stackoverflow
Solution 5 - C#AndreiView Answer on Stackoverflow
Solution 6 - C#John GroftView Answer on Stackoverflow
Solution 7 - C#samView Answer on Stackoverflow
Solution 8 - C#Andrey RavkovView Answer on Stackoverflow
Solution 9 - C#Tiago Martins PeresView Answer on Stackoverflow
Solution 10 - C#BartView Answer on Stackoverflow
Solution 11 - C#ozzView Answer on Stackoverflow
Solution 12 - C#Yagnesh KhamarView Answer on Stackoverflow
Solution 13 - C#BluebaronView Answer on Stackoverflow
Solution 14 - C#SharadView Answer on Stackoverflow
Solution 15 - C#B.NishanView Answer on Stackoverflow
Solution 16 - C#Simple SandmanView Answer on Stackoverflow
Solution 17 - C#MaccurtView Answer on Stackoverflow