2

I have An angular application (angular version Angular CLI: 8.3.26 Node: 10.13.0 OS: win32 x64 Angular: 8.2.14)

In environment.ts I have the link with my backend

    export const environment = {
      baseUrlNG: 'http://localhost:4200/',
      baseUrlApi: 'http://localhost:8082/backend/api/'
    }

The backend is a C# WebApi application. I debug it with Visual Studio with this configuration.

server configuration

I installed nuget Microsoft.AspNet.WebApi.Cors and in file WebApiConfig.cs I have this code:

    public static class WebApiConfig
    {
        [EnableCors(origins: "*", headers: "*", methods: "*")]
        public static void Register(HttpConfiguration config)
        {
            config.EnableCors();

            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{language}/{method}/{id}",
                defaults: new { method = RouteParameter.Optional, id = RouteParameter.Optional }

            );
        }
    }

And In all My backend methods I have this decorator

    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class AuthenticationController : ApiController
    {
        [Route("api/Authentication/{language}/GuestUser")]
        [HttpPost]
        [Attributes.SiteParameter_Check]
        public IHttpActionResult GuestAuthorization(string language)
        {
            //code with breakpoints never raised.
        }

In angular project I have this post

    function guest(){
      url =  `${environment.baseUrlApi}Authentication/IT/GuestUser`;
      return this.http.post(url, {}, )
        .toPromise()        
        .then(response => {
              //other code        
        })
    }

I'm getting this error

Access to XMLHttpRequest at 'http://localhost:8082/backend/api/Authentication/IT/GuestUser' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Already tried to put the file proxy.conf.json in the src folder of angular project

{
    {
        "/api/*": {
        "target": "http://localhost:8082/backend/api",
        "secure": false,
        "logLevel": "debug"
    }
}

And I put this line in file angular.json

     "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "frontend:build",
            "proxyConfig": "src/proxy.conf.json"
      },

this is my web config

    <?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
    <configSections>

        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </configSections>

    <system.web>
        <compilation debug="true" targetFramework="4.6.1" />
        <httpRuntime targetFramework="4.6.1" executionTimeout="1200" maxRequestLength="1048576" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" />
    </system.web>
    
    <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>
       
        <validation validateIntegratedModeConfiguration="false" />
        <directoryBrowse enabled="true" />
        
        <handlers>
            <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
            <remove name="OPTIONSVerbHandler" />
            <remove name="TRACEVerbHandler" />
            <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        </handlers>
    </system.webServer>

    <system.web.extensions>
        <scripting>
            <webServices>
                <jsonSerialization maxJsonLength="2147483647" />
            </webServices>
        </scripting>
    </system.web.extensions>
    
    <connectionStrings>
        ---all my connection strings
    </connectionStrings>
    <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
        <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
    </entityFramework>
    
</configuration>

What I'm missing?

Thank you very much

bedrin
  • 4,458
  • 32
  • 53
Martina
  • 1,852
  • 8
  • 41
  • 78
  • Did you try https://stackoverflow.com/a/66620352/3423750? – Phalgun Jul 03 '21 at 15:47
  • My backend is in ASP.NET WebApi not .NET Core – Martina Jul 03 '21 at 15:57
  • I've experienced issues with `methods: "*"` in the `[EnableCors]` attribute before. Have you tried explicitly stating the allowed methods? `methods: "GET,POST,PUT,PATCH,DELETE,OPTIONS"`. Also, you only need to decorate controllers / actions with `[EnableCors]`, not the config method itself. – Kurt Hamilton Jul 12 '21 at 09:42
  • This not solved my problem. I don't know how set the bounty because I don't solve my problem. – Martina Jul 13 '21 at 11:15

5 Answers5

2

Put this in WebApiConfig

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var cors = new EnableCorsAttribute("*", "*", "*");// origins, headers, methods  
            config.EnableCors(cors);

            config.MapHttpAttributeRoutes();

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

Please add those references

using Newtonsoft.Json.Serialization;

using System.Web.Http.Cors;

Note: Changes of WebApiConfig only enough. No need any configurations

Sheno Navy
  • 299
  • 1
  • 7
  • nothing to so, same error. References Newtonsoft.Json.Serialization is useless, and using System.Web.Http.Cors; was already there. – Martina Jul 03 '21 at 15:38
  • .net core or .net webApi? – Sheno Navy Jul 03 '21 at 15:52
  • it's ASP.NET WebApi – Martina Jul 03 '21 at 15:56
  • 1
    Please try to do this! 1: Inside startup.cs "ConfigureServices" method add "services.AddCors();" after "services.AddMvc().SetCompatibilityVersion(...........);". 2: Inside startup.cs "Configure" method add "app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowCredentials().WithOrigins("https://localhost:4200"));" after "app.UseHttpsRedirection();". Note: Ordering is important and remove all other related that cors. – Sheno Navy Jul 03 '21 at 16:03
  • I don't have this file (Startup.cs) in my solution – Martina Jul 03 '21 at 16:05
  • baseUrlApi: should be https not http – Sheno Navy Jul 03 '21 at 16:12
  • it's localhost, It does not change anything – Martina Jul 03 '21 at 16:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234480/discussion-between-sheno-navy-and-martina). – Sheno Navy Jul 03 '21 at 16:30
1

We used to have something like this in web.config.

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

If I recall correctly, you need to set below to allow ASP.NET app to receive and handle OPTION.

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

all details are in this article. https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

cdev
  • 5,043
  • 2
  • 33
  • 32
1

Are you sure that this port is the one that the server listens to?

I had a similar scenario not that long ago (but with java and Jboss), where the api-url's port and the listening port were different.

In my case:

  • Api-url's port: 8080
  • Listening port: 9990

So I had to set the proxy this way:

{ "/api/*": { "target": "http://localhost:9990", "secure": false, "logLevel": "debug" } }

Dharman
  • 30,962
  • 25
  • 85
  • 135
1
I also recently experienced same kind of issues while doing the same. I'm copying my MVC API codes here to help you to resolve the same. Kindly configure the same accordingly so that issue will be resolved.

WebApiConfig.cs file

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

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

web.config file (specific node webServer tag showed below)

<system.webServer>
    <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
    <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" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
    <handlers>
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <!--<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />-->
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

Add Global.asax file below method (This call specifically for PUT,POST related OPTIONS call.

 protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.Headers.AllKeys.Contains("Origin") && HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
               //   Response.AddHeader("Access-Control-Allow-Origin", "*");
               // Response.AppendHeader("Access-Control-Allow-Methods", "*");
               // Response.AddHeader("Access-Control-Max-Age", "8000");
                Response.Flush();
            }
        }

If want to restrict in controller level add below decorator in your API controller.

 [EnableCors(origins: "http://locathost:4200", headers: "*", methods: "*")]
    public class AssetsController : ApiController
Manoj
  • 36
  • 2
0

Here's an update for ASP.NET Core 6. Solutions to previous versions are an awkward fit because web.config, startup.cs, and WebApiConfig are not included by default in an ASP.NET Core 6 project.

There is a new page in the docs that explains how to set up CORS. Enable Cross-Origin Requests (CORS) in ASP.NET Core. I just used the approach "CORS with named policy and middleware" and it worked! Here's the code sample from the docs that worked for me:

var  MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      builder =>
                      {
                          builder.WithOrigins("http://example.com",
                                              "http://www.contoso.com");
                      });
});

// services.AddResponseCaching();

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthorization();

app.MapControllers();

app.Run();

On a side note, the solution in Sheno-Navy's comment worked by adding "htts://" to the origin. Here's the same code sample with Sheno-Navy's approach: var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors();

// services.AddResponseCaching();

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowCredentials().WithOrigins("https://localhost:4200"));

app.UseAuthorization();

app.MapControllers();

app.Run();
Steve Nyholm
  • 806
  • 9
  • 9