Web Api 2 处理 OPTIONS 请求

9

我有一个托管在Azure上的Web Api 2后端和一个AngularJs前端。我知道有些HTTP请求会使用OPTIONS请求进行预检查。我的问题是如何实现后端,使得如果控制器中存在处理以下GET/POST/PUT/DELETE/...的某些操作,则所有OPTIONS请求都将返回200。

2个回答

19

解决此任务的不优雅方法是在每个控制器中手动添加。

[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;
}

或者覆盖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);

  }
}

然后在配置文件中进行设置

GlobalConfiguration.Configuration.MessageHandlers.Add(new OptionsHttpMessageHandler());

即使第二个选项也不完美...没有本地内置支持


2
或者继承您自己的基类,其中包含公共的HttpResponseMessage Options()方法:public abstract class BaseApiController : ApiController - Rob Sedgwick

14

我和你遇到了同样的问题,即所谓的Preflight请求,我发现这可能与Web.Conf文件上的错误配置有关。如果存在的话,请注释或删除包含OPTIONSVerbHandler的“remove”行。

<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>

1
你是一个英雄! - JGCW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接