【问题标题】:Why does a call to an ASP.NET MVC Controller not execute a DelegatingHandler?为什么对 ASP.NET MVC 控制器的调用不执行 DelegatingHandler?
【发布时间】:2014-06-23 19:25:51
【问题描述】:

介绍问题

我最近了解到,调用 ApiController Action 会触发 DelegatingHandlerSendAsync 方法,而调用 vanilla Controller Action 不会触发它。

搜索和研究

我查看了 Web Api,并了解到它包含 HttpMessageHandler,它是 DelegatingHandler 类的父级。这使我相信 HTTP 消息处理程序通常仅作为 Web API 管道的一部分执行。

另外,Http Message Handlers run before Url Routing,因此在 Web API 和 MVC 管道之间进行选择的可能不是 URL 路由。

...考虑使用动作过滤器而不是消息处理程序[因为]动作过滤器 在执行 URI 路由后运行。

问题

  • HttpMessageHandlers 是 ASP.NET Web API 的一部分,而不是 ASP.NET MVC 的一部分吗?
  • 什么是 MVC 中的 HttpMessageHandler 等价物(图中的EQUIVALENT)?
  • 是什么导致请求遵循 Web API 管道(图中的FORK)?
  • Web API 请求与 MVC 请求有根本不同吗?

我的感觉是这样的,但请纠正我。

               Request from Client
                       |
                      IIS
                       |                           
                    ASP.NET
                       |
            HttpApplication.BeginRequest
                       |
                   et cetera
                       |
         HttpApplication.MapRequestHandler - is this what does the routing?
                       |
                     FORK                           
                   /       \
                  /         \
                 /           \
                /             \
               /               \
         **Web API**           **MVC**
              |                   |
 HttpControllerRouteHandler   MvcRouteHandler
              |                   |
    HttpControllerHandler         |    
              |                   |
    HttpMessageHandlers       EQUIVALENT?
            i.e.                  |
    DelegatingHandlers            |
            incl.                 |
    HttpServer                    |
    CustomHandlers                |
    HttpRoutingDispatcher         |
    HttpControllerDispatcher      |

有用的链接

ASP.NET Application Lifecycle

ASP.NET Web API Poster

Life Cycle of an ASP.NET MVC 5 Application

【问题讨论】:

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


    【解决方案1】:

    为什么对控制器的调用不执行委托处理程序?

    因为它们运行在两个不同的执行路径上,如果 MVC 路由匹配它然后执行 MVCHandler,而委托处理程序仅在 Api 路由匹配时执行。简而言之,上图没有正确描述拆分。

    委托处理程序在路由之后和操作选择之前运行。路由和操作选择步骤经常混淆或互换使用,尽管它们是两个不同的步骤。

    路由是将 url 与一组字符串段匹配以生成 RouteValues 的步骤,该 RouteValues 将路由键映射到路由值。 RouteValues 然后用于动作选择。委托处理程序在这两个步骤之间运行。

    在 MVC 中没有等效的委派处理程序,类似的方法是编写自己的处理程序,但您在其中陷入了一些困境,尤其是在链接生成方面。

    另一种更简单的方法是编写一个全局过滤器,但请注意,它只有在实际选择了一个动作时才会运行。

    逐行回答

    HttpMessageHandlers 是 ASP.NET Web API 的一部分,而不是 ASP.NET MVC 的一部分吗?

    是的,它们只是 WebAPI 构造。

    MVC 中的 HttpMessageHandler 等价物是什么(图中的 EQUIVALENT)?

    真的不存在,而且图表是错误的。最接近的是RouteHandler

    是什么导致请求遵循 Web API 管道(图中的 FORK)?

    匹配一个 WebAPI 路由

    Web API 请求与 MVC 请求有根本不同吗?

    不,它们不是,分叉仅在路由之后发生。

    编辑(2015 年 8 月 18 日):在 MVC Core 中,Web API 被合并到 MVC 中,并且有一个新的管道。

    【讨论】:

    • 你能扩展分叉吗? MVC 与 Web Api 路由的匹配发生在哪里?
    • 在 IIS 上运行时(这是默认设置),路由发生在 ASP.NET 中。每个路由注册一个“模式”(或真正的匹配函数)查看RouteRouteBase方法GetRouteData,当方法返回值时表示路由匹配,然后注册的(每个RouteBase对象)IRouteHandler是调用。
    • 我没有将其标记为答案,因为从阅读thisthis 来看,MvcHandler 似乎等同于HttpControllerHandler,并且HttpApplication.MapRequestHandler 在它们之间进行选择在路由期间而不是之后。
    • 路由选择一个路由,一个路由有一个路由处理器。有两个像你提到的处理程序,这就是为什么我说 MvcHandler 与委托处理程序不同,因为委托处理程序被插入到处理程序之后并且可以被链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 2014-04-28
    • 2011-11-05
    • 1970-01-01
    相关资源
    最近更新 更多