Bryan Dellinger
Bryan Dellinger

Reputation: 5294

adding cors to aspx web api 2 hybrid

I've added Web API 2 to an existing vb aspx web forms project. and the routing went into the global asax application_start because I do not have an app_start folder with WebApiConfig as you do in a standard web api project. I downloaded CORS from the nugget package manager add attempted to enable CORS

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        ' Fires when the application is started

       RouteTable.Routes.MapHttpRoute(
            name:="DefaultApi",
            routeTemplate:="api/{controller}/{id}",
            defaults:=New With {.id = RouteParameter.Optional}
        )

    Dim cors = New EnableCorsAttribute("*", "*", "*")
    GlobalConfiguration.Configuration.EnableCors(cors)

    End Sub

however whenever I attempt to run an html page that is making calls to my web api through jquery ajax I receive.

  Cross-Origin Request Blocked: The Same Origin Policy
 disallows reading the remote resource at https://xxxxx/specialdev/api/WSFobOrigin. 
(Reason: CORS header 'Access-Control-Allow-Origin' missing)

So I'm not quite sure what I am missing I attempting adding it to each controller as well.

Public Class WSFobOriginController
    Inherits ApiController
    <EnableCors("*", "*", "*")>
    <HttpGet>
    <CustomAuthentication>
    <Authorize(Roles:="WebService")>
    Public Function logon() As IHttpActionResult
        Return Ok("successfully loggon on")
    End Function

Here is the ajax call (I tried it with and without the crossDomain: true)

  this.logon = function () {
                $('#signin').prop('disabled', true);
                $.ajax({
                    url: "https://xxxxxxxx.dir.ad.dla.mil/specialdev/api/WSFobOrigin",
                    type: "GET",
                    datatype: "json",
                    crossDomain: true,
                    beforeSend: function (xhr) {
                        $('#logonSpinner').show();
                        xhr.setRequestHeader("Authorization", "Basic " + btoa(self.userName() + ":" + self.password()));
                    },
                    success: function (data) {
                        self.loggedon(true);
                    },
                    error: function (xhr, status, error) {
                        $('#signin').prop('disabled', false);
                        $('#logonSpinner').hide();
                        $('#logonError').show();
                        self.logOnErrorMessage("Status: " + xhr.status + " Message: " + xhr.statusText)
                    }
                });

            }

just noticed one more thing that is a bit odd to me. when I run the web api locally (through visual studio) and change my client jquery ajax call to the local url it works.

URL Protocol    Method  Result  Type    Received    Taken   Initiator   Wait‎‎  Start‎‎ Request‎‎   Response‎‎  Cache read‎‎    Gap‎‎
http://localhost:52851/api/WSFobOrigin  HTTP    OPTIONS 200     420 B   31 ms   CORS Preflight  0   16  0   15  0   203

and

URL Protocol    Method  Result  Type    Received    Taken   Initiator   Wait‎‎  Start‎‎ Request‎‎   Response‎‎  Cache read‎‎    Gap‎‎
http://localhost:52851/api/WSFobOrigin  HTTP    GET 200 application/json    447 B   218 ms  XMLHttpRequest  16  15  203 0   0   0

but when I change the client to point to the actual server the preflight aborts and the type no longer says OPTIONS it is null

URL Protocol    Method  Result  Type    Received    Taken   Initiator   Wait‎‎  Start‎‎ Request‎‎   Response‎‎  Cache read‎‎    Gap‎‎
https://xxxxxxx.dir.ad.dla.mil/specialdev/api/WSFobOrigin   HTTPS       (Aborted)       0 B 47 ms   CORS Preflight  0   47  0   0   0   796

some other posts had suggested adding a filter which I tried but that does not seem to work either

Imports System.Web.Http.Filters

Public Class AllowCors
    Inherits ActionFilterAttribute
    Public Overrides Sub OnActionExecuted(actionExecutedContext As HttpActionExecutedContext)
        If actionExecutedContext Is Nothing Then
            Throw New ArgumentNullException("actionExecutedContext")
        Else
            actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin")
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*")
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type")
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Methods", "GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS")
        End If
        MyBase.OnActionExecuted(actionExecutedContext)
    End Sub
End Class

and decorating my controller with allowcors

    <AllowCors>
    <EnableCors("*", "*", "*")>
    <HttpGet>
    <CustomAuthentication>
    <Authorize(Roles:="WebService")>
    Public Function logon() As IHttpActionResult
        Return Ok("successfully loggon on")
    End Function

but still no luck

status: 404
Method:  OPTIONS
Request Headers: Host: xxxxxx.dir.ad.dla.mil
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: null
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Connection: keep-alive

Response Headers:  Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
X-Frame-Options: SAMEORIGIN
Date: Wed, 23 Mar 2016 16:53:06 GMT
Content-Length: 1245

Upvotes: 2

Views: 2138

Answers (2)

Tummala Krishna Kishore
Tummala Krishna Kishore

Reputation: 8271

You can configure CORS support for the Web API at three levels:

  1. At the Global level
  2. At the Controller level
  3. At the Action level

To configure CORS support at the global level, first install the CORS package (Which you already did) and then open WebApiConfig.cs file from App_Start folder.(here you said you dont have that folder)

Dim cors = New EnableCorsAttribute("http://localhost:5901", "*", "*")
config.EnableCors(cors)

(As you are not using that method, then we will go to next Level)

Action Level

    <EnableCors(origins := "*", headers := "*", methods := "*")> 
  <HttpGet>
    <CustomAuthentication>
    <Authorize(Roles:="WebService")>
 Public Function logon() As IHttpActionResult
        Return Ok("successfully loggon on")
    End Function

In the above method you need to set parameters to allow all the headers and support all the HTTP methods by setting value to star.

Controller Level

<EnableCors(origins := "*", headers := "*", methods := "*")> _
Public Class ClassesController
    Inherits ApiController
End Class

In this you need to set parameters to allow all the headers and support all the HTTP methods by setting value to star. you can exclude one of the actions from CORS support using the [DisableCors] attribute.

So finally Here are the Attributes of EnableCors

There are three attributes pass to EnableCors:

  1. Origins: You can set more than one origins value separated by commas. If you want any origin to make AJAX request to the API then set origin value to wild card value star.
  2. Request Headers: The Request header parameter specifies which Request headers are allowed. To allow any header set value to *
  3. HTTP Methods: The methods parameter specifies which HTTP methods are allowed to access the resource. To allow all methods, use the wildcard value '*'. Otherwise set comma separated method name to allow set of methods to access the resources.

So combining above points in VB you need to Declare as below

<EnableCors(origins := "http://localhost:XXX,http://localhost:YYYY", headers := "*", methods := "POST,GET")> _
Public Class ClassesController
    Inherits ApiController
End Class

Update

Try to Add this Config to your web-config

<customHeaders> 
<add name="Access-Control-Allow-Origin" value="*" /> 
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD, OPTIONS" /> 
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /> 
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept, Authorization" /> 
</customHeaders>

Upvotes: 2

Bilgesu Erdoğan
Bilgesu Erdoğan

Reputation: 600

I think you forgot adding Microsoft.AspNet.Cors. If you use Visual Studio, you can add use this way:

Tools-> Nuget Package Manager ->Manage Nuget Packages for Solutions

You should find Microsoft.AspNet.Cors and install to api project

Upvotes: 0

Related Questions