【问题标题】:What is the complete lifecycle of an OData controller http request in WebApi 2WebApi 2 中 OData 控制器 http 请求的完整生命周期是什么
【发布时间】:2017-07-26 11:05:35
【问题描述】:
我想知道在 IIS 中托管的 ODataController 上的 odata http 请求的完整生命周期是什么。
例如:
- IIS 流水线步骤有哪些?
- 进入 ASP.NET 控制器区域时如何处理请求?
- 何时应用路由?
-
HttpPost、ApplyFilter 等属性何时应用?
【问题讨论】:
标签:
asp.net
iis
asp.net-web-api
odata
【解决方案1】:
也许这个帖子可以帮助你:
The ASP.NET Web API 2 HTTP Message Lifecycle in 43 Easy Steps
一切都从 IIS 开始:
- IIS(或 OWIN 自托管)收到请求。
然后将请求传递给HttpServer 的实例。
HttpServer 负责调度 HttpRequestMessage 对象。
HttpRequestMessage 提供对请求的强类型访问。
如果管道上存在一个或多个DelegatingHandler 的全局实例,则将请求传递给它。请求按照将所述实例添加到管道中的顺序到达 DelegatingHandler 的实例。
DelegatingHandler 实例可以跳过管道的其余部分并创建自己的响应。我在Custom Validation with FluentValidation 帖子中就是这样做的。
- 如果 HttpRequestMessage 传递了 DelegatingHandler 实例(或不存在此类处理程序),则请求继续到 HttpRoutingDispatcher 实例。
HttpRoutingDispatcher 根据匹配的路由选择要调用的路由处理程序。如果不存在这样的路由(例如 Route.Handler 为空,如图所示),则请求直接进行到步骤 10。
- 如果给定路由存在路由处理程序,则将 HttpRequestMessage 发送到该处理程序。
- 可以有DelegatingHandler attached to individual routes 的实例。如果存在此类处理程序,则请求将发送给它们(按照它们添加到管道的顺序)。
-
HttpMessageHandler 的实例然后处理请求。如果您提供自定义 HttpMessageHandler,则所述处理程序可以选择将请求返回到“主”路径或自定义端点。
- HttpControllerDispatcher 实例接收请求,该实例会将请求路由到由请求的 URL 确定的适当路由。
- HttpControllerDispatcher 选择适当的控制器将请求路由到。
- IHttpControllerSelector 的一个实例为给定的 HttpMessage 选择适当的 HttpControllerDescriptor。
- IHttpControllerSelector 调用 IHttpControllerTypeResolver 的一个实例,该实例最终会调用...
- IAssembliesResolver 的一个实例,它最终选择适当的控制器并将其从第 11 步返回给 HttpControllerDispatcher。
注意:如果您实施依赖注入,IAssembliesResolver 将被您注册的任何容器替换。
- 一旦 HttpControllerDispatcher 引用了适当的控制器,它就会调用 IHttpControllerActivator 上的 Create() 方法...
- 创建实际控制器并将其返回给 Dispatcher。然后调度程序将请求发送到 Select Controller Action 例程,如下所示。
- 我们现在有一个 ApiController 实例,它代表请求被路由到的实际控制器类。所述实例调用 IHttpActionSelector 上的 SelectAction() 方法...
- 它返回一个 HttpActionDescriptor 实例,表示需要调用的操作。
- 一旦管道确定了将请求路由到哪个操作,它就会执行插入到管道中的任何身份验证过滤器(全局或本地调用的操作)。
这些过滤器允许您对单个操作、整个控制器或整个应用程序的全局请求进行身份验证。任何存在的过滤器都按照它们添加到管道的顺序执行(首先是全局过滤器,然后是控制器级过滤器,然后是操作级过滤器)。
- 然后请求继续到 [Authorization Filters] 层,其中存在的任何授权过滤器都将应用于请求。
授权过滤器可以选择创建自己的响应并将其发回,而不是允许请求通过管道进行。这些过滤器的应用方式与身份验证过滤器相同(全局、控制器级别、操作级别)。请注意,授权过滤器只能用于请求,而不是响应,因为假设如果存在响应,则用户有权生成它。
- 请求现在进入模型绑定过程,该过程显示在主海报的下一部分。操作所需的每个参数都可以通过三个独立路径之一绑定到其值。绑定系统使用哪条路径取决于请求中所需值的位置。
- 如果实体主体中存在动作参数值所需的数据,则Web API读取请求主体; FormatterParameterBinding 的一个实例将调用适当的格式化程序类...
- 将值绑定到媒体类型(使用 MediaTypeFormatter)...
- 这会产生一个新的复杂类型。
- 如果 URL 或查询字符串中存在参数值所需的数据,则将所述 URL 传递到 IModelBinder 实例,该实例使用 IValueProvider 将值映射到模型(有关更多信息,请参阅 Phil Haack 关于此主题的帖子) ....
- 这会产生一个简单的类型。
- 如果存在自定义 HttpParameterBinding,系统将使用该自定义绑定来构建值...
- 这会导致任何类型(简单或复杂)的对象都可映射(请参阅 Mike Stall 关于此主题的精彩系列)。
- 现在请求已绑定到模型,它会通过管道中可能存在的任何操作过滤器(全局或仅用于被调用的操作)。
- 一旦通过了动作过滤器,动作本身就会被调用,系统会等待它的响应。
- 如果操作产生异常并且存在异常过滤器,则异常过滤器会接收并处理异常。
- 如果未发生异常,则该操作通过运行结果转换子例程生成一个 HttpResponseMessage 实例,如下一个屏幕截图所示。
- 如果返回类型已经是一个HttpResponseMessage,我们不需要做任何转换,所以通过返回。
- 如果返回类型为 void,.NET 将返回状态为 204 No Content 的 HttpResponseMessage。
- 如果返回类型是IHttpActionResult,调用ExecuteAsync方法创建一个HttpResponseMessage。
在您使用 return Ok(); 的任何 Web API 方法中或返回 BadRequest();或类似的东西,返回语句遵循这个过程,而不是任何其他过程,因为这些操作的返回类型是 IHttpActionResult。
- 对于所有其他类型,.NET 将创建一个 HttpResponseMessage 并将返回的序列化值放在该消息的正文中。
- 创建 HttpResponseMessage 后,将其返回到主管道。
- 通过任何可能存在的 AuthenticationFilter 传递新创建的 HttpResponseMessage。
- HttpResponseMessage 流经 HttpControllerDispatcher,此时它可能不会对它做任何事情。
- Response 也流经 HttpRoutingDispatcher,它又不会对它做任何事情。
- 现在,响应将通过任何设置为处理它的 DelegatingHandlers 进行。此时,DelegatingHandler 对象实际上只能更改正在发送的响应(例如,拦截某些响应并更改为适当的 HTTP 状态)。
- 最终的 HttpResponseMessage 被提供给 HttpServer 实例。
- 向调用客户端返回一个 Http 响应