0

I am facing a CORS policy problem and I do not know how to fix it. I tried many approaches but what makes me crazy is that the service works fine on some devices and I can utilize all its resources and works a little bit on others and does not work at others while the whole devices having the same configuration equally set. To be more clear I am having a Web application based entirely and only on AngularJS 2 and a Web API that exposes a few actions. I installed the IIS and hosted the Web API on the default Web Site, which means it can be called from port 80 for simplicity, and I hosted the Web application using port 4200. Now let's give more detail about my Web API application structure.

EMG.WebApi.Core -> this project is the core project in which I put the controller classes and the web configuration class EMG.WebApi.WebHost -> this project is used merely for hosting and it contains a reference to the EMG.WebApi.Core project and is the one that contains the Global.asax and within its Application_Start I am calling the Register method of Configuration class of the WebApi.Core and give it as a parameter the GlobalConfiguration object to register my handlers, tracers etc.

using EMG.ElectrometerWS.WebApi.Core;
using System;
using System.Web.Http;
using EMG.ElectrometerWS.WebApi.Core.Configuration;

namespace EMG.ElectrometerWS.WebApi.WebHost
{
 public class Global : System.Web.HttpApplication
 {
     protected void Application_Start(object sender, EventArgs e)
     {
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        GlobalConfiguration.Configuration.EnsureInitialized();
     }
 }
}

 using EMG.ElectrometerWS.WebApi.Core.Handlers;
 using EMG.ElectrometerWS.WebApi.Core.Tracer;
 using System;
 using System.Configuration;
 using System.Web.Http;
 using System.Web.Http.Cors;
 using System.Web.Http.Tracing;

 namespace EMG.ElectrometerWS.WebApi.Core.Configuration
{
 public static class WebApiConfig
 {
    ...

    public static string CorsOrigin
    {
        get
        {
            string result = 
            ConfigurationManager.AppSettings.Get("CorsOrigin");
            if (!string.IsNullOrEmpty(result))
            {
                return result;
            }
            throw new Exception("AppSetting CorsOrigin not found in 
            web.config file.");
        }
    }
    public static void Register(HttpConfiguration config)
    {

        // Web API configuration and services
        EnableCorsAttribute enableCors =
           new EnableCorsAttribute(CorsOrigin, "*", "*");
        config.EnableCors(enableCors);
        // Web API routes
        config.MapHttpAttributeRoutes();            
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        //config.Routes.MapHttpRoute(
        //    name: "Secret Api",
        //    routeTemplate: "secretapi/{controller}/{id}",
        //    defaults: new { id = RouteParameter.Optional },
        //    constraints: null,
        //    handler: new ApiKeyProtectionMessageHandler() {
        //        InnerHandler = new HttpControllerDispatcher(config)
        //    });

        // Enable ASP.NET Web API tracing
        //config.EnableSystemDiagnosticsTracing();
        //config.Services.Replace(typeof(ITraceWriter), new 
        // EntryExitTracer());
        //config.Services.Replace(typeof(ITraceWriter), new WebApiTracer());


        //config.MessageHandlers.Add(new EmptyPostBodyMessageHandler());
        // Message handler to check the performance in production 
        environment ONLY
        config.MessageHandlers.Add(new TracingHandler());
        //config.MessageHandlers.Add(new XHttpMethodOverrideHandler());
        config.MessageHandlers.Add(new JwtHandler());
    }
}
}

EMG.ElectrometerWS.WebApi.WebHost Web.Cofig

<appSettings>
....
<add key="CorsOrigin" value="http://localhost:4200"/>
</appSettings>

What makes me crazy is that everything works fine on my colleague laptop and he can use all the actions. On mine I cannot call some of PUT methods while I can for others on other colleague/testers they can only call GET methods!!! And increases my surprises is that after clearing the browser history/cookies one of those laptops that have only GET methods being called have all things works fine.

What I have tried:

First I added the below code as you can notice above to the configuration class

EnableCorsAttribute enableCors =
           new EnableCorsAttribute(CorsOrigin, "*", "*");
        config.EnableCors(enableCors);

Creating the following handler and registered it as the first handler before other handlers

 public class CorsPreflightHandler : DelegatingHandler
 {
 protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage 
 request,
 CancellationToken cancellationToken)
{
if (request.Headers.Contains("Origin") && request.Method == HttpMethod.Options)
{
   var response = new HttpResponseMessage(HttpStatusCode.OK);
   response.Headers.Add("Access-Control-Allow-Origin", "*");
   response.Headers.Add("Access-Control-Allow-Methods", "*");

   return response;
}
   return await base.SendAsync(request, cancellationToken);
}
}

Removing the previous code and configured the CORS using the Web.config file of the WebHost project

<system.webServer>
     <httpProtocol>
         <customHeaders>
            <add name="Access-Control-Allow-Origin" value="http:localhost:4200" />
            <add name="Access-Control-Allow-Methods" value="*" />
            <add name="Access-Control-Allow-Headers" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

Finally removing the web config tags and enabled if on each controller class

[EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*")]
public class XXXController : ApiController
{
   Public string Get(int id)
   {
       return "value";
   }
}
Mind Optimizer
  • 175
  • 3
  • 13

1 Answers1

0

The CORS issue seems solved in meantime. I used the first approach by setting an application setting key/value for the allowed Origin then use that key/value to retrieve and register that Origin through a CORS attribute.

<appSettings>
....
<add key="CorsOrigin" value="http://localhost:4200"/>
</appSettings>

public static string CorsOrigin
{
        get
        {
            string result = 
                   ConfigurationManager.AppSettings.Get("CorsOrigin");
            if (!string.IsNullOrEmpty(result))
            {
                return result;
            }
            throw new Exception("AppSetting CorsOrigin not found in web.config file.");
        }
}

public static void Register(HttpConfiguration config)
{
 ....
 EnableCorsAttribute enableCors =
       new EnableCorsAttribute(CorsOrigin, "*", "*");
    config.EnableCors(enableCors);
}

However, I still do not know what cause the problem from the beginning it may be an IIS issue or missing feature etc.

Mind Optimizer
  • 175
  • 3
  • 13