Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Web API CORS PreFlight Request

Tags:

I have some trouble make PUT and DELETE CORS request to Web API on other domain.

I've coded API by tutorial http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#create-webapi-project.

GET and POST Requests works fine, but DELETE and PUT doesn't. I get this message:

Failed to load resource: the server responded with a status of 405 (Method Not Allowed) Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource. 

When I add code to WebConfig suggested on CORS support for PUT and DELETE with ASP.NET Web API , I get only first error.

Can anyone help me with this please?

like image 706
Milan Gatyas Avatar asked Dec 27 '13 00:12

Milan Gatyas


People also ask

How do you handle CORS preflight request?

A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method , Access-Control-Request-Headers , and the Origin header.

Is preflight request necessary?

This opt-in is the preflight request. So GET/POST requests without any custom headers don't need a preflight, since these requests were already possible before CORS. But any request with custom headers, or PUT/DELETE requests, do need a preflight, since these are new to the CORS spec.


2 Answers

You can add a handler to deal with this type of request.

Create a class derive from "DelegatingHandler":

public class PreflightRequestsHandler : DelegatingHandler {     protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)     {         if (request.Headers.Contains("Origin") && request.Method.Method.Equals("OPTIONS"))         {             var response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK };             // Define and add values to variables: origins, headers, methods (can be global)                            response.Headers.Add("Access-Control-Allow-Origin", origins);             response.Headers.Add("Access-Control-Allow-Headers", headers);             response.Headers.Add("Access-Control-Allow-Methods", methods);             var tsc = new TaskCompletionSource<HttpResponseMessage>();             tsc.SetResult(response);             return tsc.Task;         }         return base.SendAsync(request, cancellationToken);     }  } 

Later in WebApiconfig.cs in Register method add this:

public static void Register(HttpConfiguration config) {     // Define and add values to variables: origins, headers, methods (can be global)      // Enable global CORS     config.EnableCors(new EnableCorsAttribute(origins, headers, methods));      // Add handler to deal with preflight requests, this is the important part     config.MessageHandlers.Add(new PreflightRequestsHandler()); // Defined above     .     .     . } 
like image 182
MCurbelo Avatar answered Sep 18 '22 12:09

MCurbelo


The AJAX call you're doing to the Web API is triggering a Preflight check (HTTP verb "OPTIONS"). This needs to be handled by your system otherwise you'll get the 405 error. There are a few answers on how to do that here on SO, like:

Handling CORS Preflight requests to ASP.NET MVC actions

You can also avoid this preflight call altogether if you follow the following guidelines.

The browser can skip the preflight request if the following conditions are true:  The request method is GET, HEAD, or POST, **and** The application does not set any request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID, **and** The Content-Type header (if set) is one of the following:  - application/x-www-form-urlencoded  - multipart/form-data  - text/plain 

Taken from http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api (under "Preflight Requests"):

like image 43
Dominik Avatar answered Sep 17 '22 12:09

Dominik