是否可以通过请求动词选择自定义处理程序?

时间:2015-07-08 06:53:17

标签: asp.net asp.net-mvc asp.net-web-api

我编写了一个自定义处理程序来处理带有OPTIONS动词的请求。

public class OptionsRequestHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string origin = context.Request.Headers.Get("Origin");
        context.Response.AddHeader("Access-Control-Allow-Origin", origin);
        context.Response.AddHeader("Access-Control-Allow-Methods", "*");
        context.Response.AddHeader("Access-Control-Allow-Headers", "accept, authorization, content-type");
    }

    public bool IsReusable
    {
        get { return false; }
    }
}

并已在web.config中注册此处理程序。

<system.webServer>
<modules>
  ......
</modules>
<handlers>
......
  <add name="OptionsHandler" path="*" verb="OPTIONS" type="REAMS.Infrastructure.RequestHandlers.OptionsRequestHandler"/>   
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,DELETE,PUT,HEAD" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

但是从不为选项请求选择处理程序。有什么不对的吗?谢谢!

1 个答案:

答案 0 :(得分:0)

终于找到了这个问题。因为默认情况下,MVC框架通过路径将请求映射到处理程序,所以不可能通过请求动词将处理程序映射到请求。

为此,我需要抢占MVC的处理程序选择并实现我自己的模块。这是任何感兴趣的人的工作副本。

public class OptionsVerbModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostRequestHandlerExecute += onPostRequestHandlerExecute;
        context.PostResolveRequestCache += onPostResolveRequestCache;
    }

    private void onPostResolveRequestCache(object sender, EventArgs eventArgs)
    {
        if (string.Equals(HttpContext.Current.Request.HttpMethod, "OPTIONS", StringComparison.OrdinalIgnoreCase))
        {
            HttpContext.Current.RemapHandler(new OptionsRequestHandler());
        }
    }

    private void onPostRequestHandlerExecute(object sender, EventArgs e)
    {
        string origin = HttpContext.Current.Request.Headers.Get("Origin");

        if (origin != null)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
        }
    }

    public void Dispose()
    {
    }
}

该模块的作用是检查请求的动词以及它是否属于&#39; OPTIONS&#39;请求,在问题中选择我的自定义处理程序,而不是映射到MVC处理程序。

我这样做是因为我发现现有的EnableCors for Web API不适合我的应用程序需求,并且通过使用这个自定义过程,我也有更多的控制权。