Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS + ASP.NET Web API Cross-Domain Issue

Moving forward with my mobile app development learning process, I've found a new obstacle: Cross-origin Request Sharing or CORS.

I am using a combination of AngularJS + jQuery Mobile (Cordova phone client) and ASP.NET Web API (backend). My issue is that I have not been able to complete a POST request (or any other type of request) to an API controller.

My AngularJS controller uses the $http.post() service method to call the Web API controller. However, Chrome debugger says that the call failed in an OPTIONS request (possibly the CORS preflight request).

I have implemented the CORS action selector from the following post: Enabling CORS in Web API Project. Even tough I can call the api method from Fiddler, AngularJS keeps failing on the OPTIONS preflight request.

Is there anything I should be aware of about AngularJS and cross-domain calls? Any possible solution to my predicament?

Thanks.

like image 729
Luis Aguilar Avatar asked Aug 02 '12 22:08

Luis Aguilar


People also ask

How do I enable cross domain in Web API?

You can enable CORS per action, per controller, or globally for all Web API controllers in your application. To enable CORS for a single action, set the [EnableCors] attribute on the action method.

Can we use Angular JS in asp net?

Using AngularJS in ASP.NETAfter selecting Web, select ASP.NET Web Application (. NET Framework) under The Web. We need to give the project name in name column, which looks, as shown below. Project template Window will open after clicking OK button.

What is cross in Web API?

CORS is a W3C standard that allows you to get away from the same origin policy adopted by the browsers to restrict access from one domain to resources belonging to another domain. You can enable CORS for your Web API using the respective Web API package (depending on the version of Web API in use) or OWIN middleware.


2 Answers

You can skip the preflight option request by using content-type : application/x-www-form-urlencoded.

AngularJS:

var user = {
   ID: 1,
   Name: 'test'
};

$http({
  url: "api.localhost/api/users/addUser",
  method: "POST",
  data: $.param(user),
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  withCredentials: true,
  }).success(function (data, status, headers, config) {
     console.log(data);
})

Web api:

[HttpPost]
public string AddUser(User user)
{
    // Do something
    return user.Name + " added";
}

Web.config

    <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
            <handlers>
                <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
                <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
                <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
                <remove name="OPTIONSVerbHandler" />
                <remove name="TRACEVerbHandler" />

                <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
                <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
                <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
            </handlers>
            <httpProtocol>
                <customHeaders>
                    <add name="Access-Control-Allow-Origin" value="http://localhost" />
                    <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Cache-Control" />
                    <add name="Access-Control-Allow-Credentials" value="true" />
                    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
                </customHeaders>
            </httpProtocol>
      </system.webServer>
like image 117
Henke Avatar answered Oct 21 '22 16:10

Henke


While stumbling onto this issue with AngularJS 1.3 with Microsoft Web API 2 I found a simple solution to the CORS configuration issue.

  • First from Nuget intall - Microsoft WebApi Cors

    Install-Package Microsoft.AspNet.WebApi.Cors
    
  • Then in your WebApiConfig.cs file:

    var cors = new System.Web.Http.Cors.EnableCorsAttribute("www.my-angular-web-site.com", "*", "*");
    
    config.EnableCors(cors);
    

You can also enable CORS everywhere with a * instead of your web site but that defeats the purpose of CORS and opens up security holes - but you can do it for testing.

The WebApi.Cors assembly also lets you enable cors controller by controller or with other more granular details. Other details can be found here on the Web API site.

like image 3
kmcnamee Avatar answered Oct 21 '22 16:10

kmcnamee