ASP.NET WEB API处理流程
前言:大图请看 http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster.pdf
Web Api Hosting
我们不仅可以通过Web应用程序作为Web api的宿主,也可以使用任意的托管应用,如控制台程序,这个时候我们只需加载Web Api的类库。
- Hosting:当我们使用asp.net应用作为web api的宿主,那么生命周期将开始于HttpControllerHandler,HttpControllerHandler是IHttpControllerHandler接口的实现,它负责创建请求,并把请求带入web api的服务管道。
- SelfHosting:当我们使用自我宿主时。那么服务管道的生命周期将从HttpSelfHostServer 开始,HttpSelfHostServer 是HttpServer 的子类,HttpSelfHostServer 具有监听、接收以及对请求进行相应的能力。
HttpConfiguration
HttpConfiguration在WebApi中比较重要,代表了WebAPi的一个全局配置。如果想要扩展WebApi,一般要对HttpConfiguration进行自定义的配置,修改webapi原有的实现,替换成自己的实现。具体的属性如下表。
表格 1
名称 |
说明 |
获取或设置与此实例关联的依赖关系解析程序。 |
|
获取适用于所有使用此 HttpConfiguration 实例提供的请求的筛选器列表。 |
|
获取此实例的媒体类型格式化程序。 |
|
获取或设置一个值,该值指示是否应在错误消息中包含错误详细信息。 |
|
获取或设置在使用 HttpConfiguration 实例处理请求之前将执行该实例的最终初始化的操作。 |
|
获取当 HttpRequestMessage 在堆栈中向上遍历,且 HttpResponseMessage 在堆栈中向下遍历以进行回应时要调用的 DelegatingHandler 实例的排序列表。 |
|
与参数绑定方式相关的规则的集合。 |
|
获取与此实例关联的属性。 |
|
获取与此 HttpConfiguration 实例关联的 HttpRouteCollection。 |
|
获取与此实例关联的默认服务的容器。 |
|
获取根虚拟路径。 |
HttpControllerHandler
想对于MVC来说MVC的IHandler为MVCHandler,WebAPi的IHander为HttpControllerHandler,它们都会在注册路由的时候被映射,与MVC不同的是,HttpControllerHandler将会被设置成单例。HttpControllerHandler会根据Request来创建出HttpRequestMessage。
HttpRequestMessage、HttpResponseMessage
这两个对象实际上就是对我们熟悉的HttpRequest和HttpResponse的封装,web api里面请求的输入输出都是由这两个对象来完成的,HttpRequestMessage除了包含了HttpRequest的基本信息。HttpRequestMessage具体的属性如下:
表格 2
名称 |
说明 |
获取或设置 HTTP 消息的内容。 |
|
获取 HTTP 请求标头的集合。 |
|
获取或设置 HTTP 请求信息使用的 HTTP 方法。 |
|
获取 HTTP 请求的属性集。 |
|
获取或设置 HTTP 请求的 Uri。 |
|
获取或设置 HTTP 消息版本。 |
HTTP Message Handlers
HTTP Message handlers是进入web api处理管道的第一步,请求进入管道后将会经过一系列的Message handler进行加工处理,我们也可以加入自定义的Message Handler,这些Message handler都是DelegatingHandler 的子类。
这些Message Handler可以是全局的也可以是针对于某个特殊的请求,这些特殊的请求,我们可以在设置路由的时候进行配置。(请看HttpRoutingDispatcher)
Delegating Handler
Delegating Handler是web pai中一个重要的扩展点。Delegating Handler位于Web api处理管道的前端,基本上是每个请求的必经之路。
在图上我也能看到Response的输出也是要进入Delegating Handler。这些自定义的处理可以是请求的监视、请求的筛选、或者是异常处理。
这里的Delegating Handler不仅仅只有一个,我们可以在HttpConfiguration进行配置,加入自定义的Delegating Handler。Delegating Handler的处理将形成一个链路,第一个Delegating Handler处理完后交由下一个Delegating Handler来处理,当没有自定义的Delegating Handler进行处理的时候,web api会调用HttpRoutingDispatcher(实际上HttpRoutingDispatcher也是DelegatingHandler的子类,而且HttpServer也是DelegatingHandler的子类)。DelegatingHandler的代码如下(删掉了写无关紧要的代码)。
public abstract class DelegatingHandler : HttpMessageHandler
{
private HttpMessageHandler innerHandler;//具有一个ttpMessageHandler的属性
protected DelegatingHandler(HttpMessageHandler innerHandler)
{
this.InnerHandler = innerHandler;
} protected internal override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request == null)
throw new ArgumentNullException("request", SR.net_http_handler_norequest);
this.SetOperationStarted();
return this.innerHandler.SendAsync(request, cancellationToken);//直接调用innerHandler的方法
}
} public abstract class HttpMessageHandler : IDisposable
{
protected internal abstract Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
}
HttpRoutingDispatcher
如果自定义的Delegating Handler处理完了,那么请求将会被HttpRoutingDispatcher来处理,顾名思义,“Http路由分发器”,他会判断当前请求的路由数据里面是否包含Handler属性,默认情况下都是空的,因为我们在映射web api的路由时默认没有指定Handler的。如果有,web api会将请求直接交由这个Handler处理,并且返回,而不经过后面的步骤,如Controller激活、模型绑定等等。
如果我们对某个路由映射了指定的Handler,处理完后想要继续执行Controller、Actioin等之后的操作也是可以的,我们只要把一个相互链接好的Handler链映射给这个路由。
具体做法请看:http://www.asp.net/web-api/overview/working-with-http/http-message-handlers
HttpControllerDispatcher
HttpControllerDispatcher所做的事情就是将请求分发给具体的Controller。我们想一下,现在我们能拿就是HttpRequestMessage,通过HttpRequestMessage我们还可以拿到路由数据,在路由数据中我们就能得到Controller的名称。知道一个类的名称,那我们该如何创建它呢?我们首先应该要获取这个类的类型(Type),获取这个类的类型(Type)的工作就由IHttpControllerTypeResolver来做,但是要得到这个类的类型我们就必须知道这个类所在的程序集(Assembly)这个工作就由IAssembliesResolver来做。图中我们可以看到IHttpController返回的类型是HttpControllerDescriptor(实际上就是对于Controller类的描述,相对应的还有HttpActionDescriptor、HttprParameteDescriptor,这和MVC是类似的。拿到HttpControllerDescriptor对象后就应该对Controller进行激活。
IHttpControllerActivator
Controller的激活依赖于IHttpControllerActivator,而IHttpControllerActivator的调用又依赖于IDependencyResolver(依赖注入的方式)。具体体来说IHttpControllerActivator要对Controller激活,首选采用IDependencyResolver方式激活,并且返回IHttpController,如果返回的IHttpController是空,那就采用反射的形式激活。
但是对于IDependencyResolver的默认实现为EmptyResolver,EmptyResolver永远都是返回空。
Select Controller Action
找到了正确的Controller之后,我们就应该去找对应的Action,web api中通过IHttpActionSelector接口返回一个HttpActionDescriptor对象,HttpActionDescriptor和上面的HttpControllerDescriptor类似,是对于Action的描述。截止到这一步,实际上还没有真正的执行Action,而是创建出了HttpActionDescriptor对象。
Authorization Filters
在创建HttpActionDescriptor对象时,各种Filters也会被初始化,首先请求将先进入Authorization Filters进行权限的判断,如果通过,进入下一步,如果不通过直接返回。
Model Binding
请求分为三部分URI、Header、Entity-body。
- URI Binding:对于URI上的参数,web api使用ModelBinderParameterBinding进行处理,ModelBinderParameterBinding的处理跟MVC类似,需要依赖IModelBinder和IValueProvoder。
- Formatter Binding:对于请求体,Web Api会使用FormatterBinding对参数进行绑定。
- HTTP parameter binding:如果我们想对整个请求进行绑定,则需要我们需要有一个自定义的ModelBinder。
Action Filter
当完成了模型绑定的任务之后,就开始进入Action Filter,它会被执行两次,分别是在OnExecuting和OnExecution事件是被调用。
Action Invoker
IHttpActionInvoke的作用就是激活Action,并且返回HttpResponseMessage。激活Action是通过调用HttpActionDescriptor(表示对于action方法的描述)对象中的ExecuteAsync方法。而HttpResponseMessage的返回则由ResultConverter完成。
ResultConverter
IActionResultConverter的接口通过唯一的方法Converter实现。针对返回值的不同,转换的类型也不同。
- HttpResponseMessage:如果Action方法的返回值是HttpResponseMessage则无需转化。
- Void:若果是无返回值,将返回一个空的HttpResponseMessage。
- ValueResultConverter<T>:这种情况下,会通过IContentNegotiator根据请求期望得到的媒体类型,而选择相对应的MediaTypeFormatter进行序列化。
截止到这一步,已经完成了对于HttpResponse对象的创建,接下来HttpResponse就会沿着相反的路程返回给客户端。
p.s.如果错误,请指正,谢谢!
参考:
ASP.NET-Web-API-Poster:http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster.pdf
asp.net webapi :http://www.asp.net/web-api
Lifecycle of an ASP.NET Web API Message:http://www.dotnetcurry.com/ShowArticle.aspx?ID=888
ASP.NET WEB API处理流程的更多相关文章
- 总体介绍ASP.NET Web API下Controller的激活与释放流程
通过<ASP.NET Web API的Controller是如何被创建的?>我们已经对HttpController激活系统的核心对象有了深刻的了解,这些对象包括用于解析程序集和有效Http ...
- ASP.NET Web API Model-ModelBinder
ASP.NET Web API Model-ModelBinder 前言 本篇中会为大家介绍在ASP.NET Web API中ModelBinder的绑定原理以及涉及到的一些对象模型,还有简单的Mod ...
- ASP.NET Web API 控制器执行过程(一)
ASP.NET Web API 控制器执行过程(一) 前言 前面两篇讲解了控制器的创建过程,只是从框架源码的角度去简单的了解,在控制器创建过后所执行的过程也是尤为重要的,本篇就来简单的说明一下控制器在 ...
- ASP.NET Web API 管道模型
ASP.NET Web API 管道模型 前言 ASP.NET Web API是一个独立的框架,也有着自己的一套消息处理管道,不管是在WebHost宿主环境还是在SelfHost宿主环境请求和响应都是 ...
- ASP.NET Web API 路由对象介绍
ASP.NET Web API 路由对象介绍 前言 在ASP.NET.ASP.NET MVC和ASP.NET Web API这些框架中都会发现有路由的身影,它们的原理都差不多,只不过在不同的环境下作了 ...
- How ASP.NET Web API 2.0 Works?[持续更新中…]
一.概述 RESTful Web API [Web标准篇]RESTful Web API [设计篇] 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用 二.路由 ...
- 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持, ...
- 《ASP.NET Web API 2框架揭秘》样章(PDF版本)
<ASP.NET Web API 2框架揭秘>(详情请见<新作<ASP.NET Web API 2框架揭秘>正式出版>)以实例演示的方式介绍了很多与ASP.NET ...
- 新作《ASP.NET Web API 2框架揭秘》正式出版
我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西.对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠.如果我们将整个“ ...
随机推荐
- 牛客练习赛 29 E 位运算?位运算!(线段树)
题目链接 牛客练习赛29E 对$20$位分别建立线段树.首先$1$和$2$可以合起来搞(左移右移其实是等效的) 用个lazy标记下.转移的时候加个中间变量. $3$和$4$其实就是区间$01$覆盖操 ...
- BZOJ2654/COGS1764 [2012国家集训队]tree(陈立杰) [生成树,二分]
BZOJ传送门,COGS传送门 tree Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V, ...
- 洛谷P2874 [USACO07FEB]新牛棚Building A New Barn [贪心]
题目传送门 题目描述 After scrimping and saving for years, Farmer John has decided to build a new barn. He wan ...
- C++中的error C2662,const的this指针问题
今天在写C++代码的时候遇到一个错误,涉及到了常量的this指针的问题. 简化后的代码如下: #include <iostream> #include <string> usi ...
- WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping——牛腩新闻发布系统
VS2011使用验证控件出现" WebForms UnobtrusiveValidationMode 需要"jquery"ScriptResourceMapping.请添 ...
- HDU 6060 RXD and dividing(LCA)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6060 [题目大意] 给一个n个节点的树,要求将2-n号节点分成k部分, 然后将每一部分加上节点1, ...
- BZOJ 1150 [CTSC2007]数据备份Backup(贪心+优先队列)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1150 [题目大意] 给出n个数,请你挑出k对(每个数不可重复选取),使得他们差的绝对值 ...
- 【推导】【构造】Petrozavodsk Summer Training Camp 2015 Day 2: Xudyh (TooSimple) Contest, Saturday, August 22, 2015 Problem G. Travelling Salesman Problem
一个矩阵,每个位置有一个非负整数,一个人从左上走到右下,不能走重复的格子,问得到的最大权值. 当长宽不都为偶数时,必然能走遍所有格子,横着从左到右,从右到左(或是竖着走)走完即可. 当长宽都是偶数时, ...
- 【计算几何】【极角排序】Gym - 101174B - Bribing Eve
把每件物品当成平面上一个点,将第一件物品放在原点.那个权重值相当于一条直线,于是相当于直线绕原点转一圈,统计上侧点的数量. 队友的代码: #include <cmath> #include ...
- 浅谈分布式CAP定理
互联网发展到现在,由于数据量大.操作并发高等问题,大部分网站项目都采用分布式的架构.而分布式系统最大的特点数据分散,在不同网络节点在某些时刻(数据未同步完,数据丢失),数据会不一致. 在2000年,E ...