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

名称

说明

DependencyResolver

获取或设置与此实例关联的依赖关系解析程序。

Filters

获取适用于所有使用此 HttpConfiguration 实例提供的请求的筛选器列表。

Formatters

获取此实例的媒体类型格式化程序。

IncludeErrorDetailPolicy

获取或设置一个值,该值指示是否应在错误消息中包含错误详细信息。

Initializer

获取或设置在使用 HttpConfiguration 实例处理请求之前将执行该实例的最终初始化的操作。

MessageHandlers

获取当 HttpRequestMessage 在堆栈中向上遍历,且 HttpResponseMessage 在堆栈中向下遍历以进行回应时要调用的 DelegatingHandler 实例的排序列表。

ParameterBindingRules

与参数绑定方式相关的规则的集合。

Properties

获取与此实例关联的属性。

Routes

获取与此 HttpConfiguration 实例关联的 HttpRouteCollection

Services

获取与此实例关联的默认服务的容器。

VirtualPathRoot

获取根虚拟路径。

 

HttpControllerHandler

想对于MVC来说MVC的IHandler为MVCHandler,WebAPi的IHander为HttpControllerHandler,它们都会在注册路由的时候被映射,与MVC不同的是,HttpControllerHandler将会被设置成单例。HttpControllerHandler会根据Request来创建出HttpRequestMessage。

HttpRequestMessage、HttpResponseMessage

这两个对象实际上就是对我们熟悉的HttpRequest和HttpResponse的封装,web api里面请求的输入输出都是由这两个对象来完成的,HttpRequestMessage除了包含了HttpRequest的基本信息。HttpRequestMessage具体的属性如下:

 表格 2

名称

说明

Content

获取或设置 HTTP 消息的内容。

Headers

获取 HTTP 请求标头的集合。

Method

获取或设置 HTTP 请求信息使用的 HTTP 方法。

Properties

获取 HTTP 请求的属性集。

RequestUri

获取或设置 HTTP 请求的 Uri

Version

获取或设置 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

posted @ 2013-07-27 14:01  王土垚  阅读(2274)  评论(2编辑  收藏  举报