Click here to Skip to main content
15,884,472 members

Asp.net web API CORS problem

Amr Mohammad Rashad asked:

Open original thread
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.

C#
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();
        }
    }
}


C#
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

XML
<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:

I tried a lot of approaches

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


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

C#
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

XML
<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

C#
[EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*")]
    public class XXXController : ApiController
    {
       Public string Get(int id)
       {
           return "value";
       }
    }
Tags: ASP.NET, WebAPI2

Plain Text
ASM
ASP
ASP.NET
BASIC
BAT
C#
C++
COBOL
CoffeeScript
CSS
Dart
dbase
F#
FORTRAN
HTML
Java
Javascript
Kotlin
Lua
MIDL
MSIL
ObjectiveC
Pascal
PERL
PHP
PowerShell
Python
Razor
Ruby
Scala
Shell
SLN
SQL
Swift
T4
Terminal
TypeScript
VB
VBScript
XML
YAML

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  4. Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the http://www.codeproject.com/info/cpol10.aspx.



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900