9

I need to enable CORS for my Web API and I can't upgrade to Framework 4.5 at the moment. (I know about System.Web.Http.Cors.EnableCorsAttribute.)

I've tried to add the following to my Web.config to see if it worked, but it didn't:

<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*"/> </customHeaders> </httpProtocol> 

I've also tried to set the Access-Control-Allow-Origin header to "*" manually by use of System.Web.Http.Filters.ActionFilterAttribute (based on this post: Add custom header to all responses in Web API) - but that didn't work out either as the request is rejected before it gets to the action filtering.

So I'm kinda stuck now.. Any help is appreciated.

Edit: Turns out

<add name="Access-Control-Allow-Origin" value="*"/> 

was the answer all along, I must've done something wrong previously when I tested it. But this solution means that all actions are CORS enabled (which will do for now).

4
  • possible duplicate of The requested resource does not support http method 'GET'. Error Code 405 Commented Oct 22, 2014 at 11:27
  • @ArindamNayak The accepted answer in that thread seems to require .NET Framework 4.5. Commented Oct 22, 2014 at 11:41
  • do one thing, follow, the steps mentioned in answer there, and you may have to search for .net 4 nuget package to make it work. Note: I have answered there, so i not answering it here, i mean not making a copy of that. Commented Oct 22, 2014 at 11:48
  • stackoverflow.com/questions/22143378/… - this says CORS is not there in WEB API 1.- Added my answer too! Commented Oct 22, 2014 at 11:54

3 Answers 3

11

POST, PUT, DELETE, etc use pre-flighted CORS. The browser sends an OPTIONS request. This is because browser first, checks if serverside can handle CORS or not using OPTIONS request, if succeeds, then sends actual request PUT or POST or Delete. Since you do not have an action method that handles OPTIONS, you are getting a 405. In its most simplest form, you must implement an action method like this in your controller.

More explanation - http://www.w3.org/TR/cors/#resource-preflight-requests

http://www.html5rocks.com/en/tutorials/cors/

public HttpResponseMessage Options() { var response = new HttpResponseMessage(); response.StatusCode = HttpStatusCode.OK; return response; } 

Note: This this action just responds to OPTION request, so along with this you need to add necessary config to web.config, such as Access-Control-Allow-Origin = * and Access-Control-Allow-Methods = POST,PUT,DELETE.

Web API 2 has CORS support, but with Web API 1, you have to follow this path.

Sign up to request clarification or add additional context in comments.

Comments

9

try to add also:

 <add name="Access-Control-Allow-Headers" value="*" /> 

5 Comments

where to add this, I tried adding in web config, but not working
@Md.ParvezAlam add it to web.config gist.github.com/walkermatt/637df93121a409faab6a
I am accessing method from jquery, and it is web api -1
@Md.ParvezAlam it may be better to create a new question for that, like discuss it here.
1

I had faced the lot of issue with webAPI 1 Cross domain access finally able to fix it have a look at my blog http://keerthirb.blogspot.in/2017/08/making-cross-enable-for-webapi1.html

Cross code is

public class CorsHandler : DelegatingHandler { const string Origin = "Origin"; const string AccessControlRequestMethod = "Access-Control-Request-Method"; const string AccessControlRequestHeaders = "Access-Control-Request-Headers"; const string AccessControlAllowOrigin = "Access-Control-Allow-Origin"; const string AccessControlAllowMethods = "Access-Control-Allow-Methods"; const string AccessControlAllowHeaders = "Access-Control-Allow-Headers"; protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { bool isCorsRequest = request.Headers.Contains(Origin); bool isPreflightRequest = request.Method == HttpMethod.Options; if (isCorsRequest) { if (isPreflightRequest) { return Task.Factory.StartNew<HttpResponseMessage>(() => { HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First()); string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault(); if (accessControlRequestMethod != null) { response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod); } string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders)); if (!string.IsNullOrEmpty(requestedHeaders)) { response.Headers.Add(AccessControlAllowHeaders, requestedHeaders); } return response; }, cancellationToken); } else { return base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t => { HttpResponseMessage resp = t.Result; resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First()); return resp; }); } } else { return base.SendAsync(request, cancellationToken); } } } 

2 Comments

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
I Agree So i have included cross enable code. For more info user can go to the link.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.