I have Web Api 2 backend hosted on Azure and AngularJs forntend. I understand that some of HTTP request use pre-check with OPTIONS request. My question is how to implement backend that way, that all OPTIONS requests will return 200 if there is some action in controller that will handle following GET/POST/PUT/DELETE/....
Asked
Active
Viewed 1.4k times
9
Matjaž
- 2,096
- 3
- 35
- 55
2 Answers
19
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
Vladimir
- 1,380
- 2
- 19
- 23
-
2or inherit from your own base class which contains your public HttpResponseMessage Options() method: public abstract class BaseApiController : ApiController – Rob Sedgwick Jan 05 '18 at 16:23
14
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>
Alessandro R
- 525
- 7
- 16