Web Api 2 Handle OPTIONS Requests
Solution 1
Non elegant way to solve this task is adding in each controller manually
[AcceptVerbs("OPTIONS")]
public HttpResponseMessage Options()
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Headers.Add("Access-Control-Allow-Origin", "*");
resp.Headers.Add("Access-Control-Allow-Methods", "GET,DELETE");
return resp;
}
Or override MessageHandlers
public class OptionsHttpMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Method == HttpMethod.Options)
{
var apiExplorer = GlobalConfiguration.Configuration.Services.GetApiExplorer();
var controllerRequested = request.GetRouteData().Values["controller"] as string;
var supportedMethods = apiExplorer.ApiDescriptions.Where(d =>
{
var controller = d.ActionDescriptor.ControllerDescriptor.ControllerName;
return string.Equals(
controller, controllerRequested, StringComparison.OrdinalIgnoreCase);
})
.Select(d => d.HttpMethod.Method)
.Distinct();
if (!supportedMethods.Any())
return Task.Factory.StartNew(
() => request.CreateResponse(HttpStatusCode.NotFound));
return Task.Factory.StartNew(() =>
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Headers.Add("Access-Control-Allow-Origin", "*");
resp.Headers.Add(
"Access-Control-Allow-Methods", string.Join(",", supportedMethods));
return resp;
});
}
return base.SendAsync(request, cancellationToken);
}
}
and then in config
GlobalConfiguration.Configuration.MessageHandlers.Add(new OptionsHttpMessageHandler());
even second option is not perfect though... no native build in support
Solution 2
I had the same issue as you, the so called Preflight request, and I figured out that this might be related to a misconfiguration on the Web.Conf file. Comment out or remove, if present, the line containing the "remove" of the OPTIONSVerbHandler.
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<!--<remove name="OPTIONSVerbHandler" /> -->
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Related videos on Youtube
Comments
-
Matjaž over 1 year
I have
Web Api 2
backend hosted on Azure andAngularJs
forntend. I understand that some ofHTTP request
use pre-check withOPTIONS request
. My question is how to implement backend that way, that allOPTIONS requests
will return 200 if there is some action in controller that will handle followingGET/POST/PUT/DELETE/...
. -
Rob Sedgwick over 6 yearsor inherit from your own base class which contains your public HttpResponseMessage Options() method: public abstract class BaseApiController : ApiController
-
JGCW almost 6 yearsYou are a hero!