前言:大图请看 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

ASP.NET WEB API处理流程的更多相关文章

  1. 总体介绍ASP.NET Web API下Controller的激活与释放流程

    通过<ASP.NET Web API的Controller是如何被创建的?>我们已经对HttpController激活系统的核心对象有了深刻的了解,这些对象包括用于解析程序集和有效Http ...

  2. ASP.NET Web API Model-ModelBinder

    ASP.NET Web API Model-ModelBinder 前言 本篇中会为大家介绍在ASP.NET Web API中ModelBinder的绑定原理以及涉及到的一些对象模型,还有简单的Mod ...

  3. ASP.NET Web API 控制器执行过程(一)

    ASP.NET Web API 控制器执行过程(一) 前言 前面两篇讲解了控制器的创建过程,只是从框架源码的角度去简单的了解,在控制器创建过后所执行的过程也是尤为重要的,本篇就来简单的说明一下控制器在 ...

  4. ASP.NET Web API 管道模型

    ASP.NET Web API 管道模型 前言 ASP.NET Web API是一个独立的框架,也有着自己的一套消息处理管道,不管是在WebHost宿主环境还是在SelfHost宿主环境请求和响应都是 ...

  5. ASP.NET Web API 路由对象介绍

    ASP.NET Web API 路由对象介绍 前言 在ASP.NET.ASP.NET MVC和ASP.NET Web API这些框架中都会发现有路由的身影,它们的原理都差不多,只不过在不同的环境下作了 ...

  6. How ASP.NET Web API 2.0 Works?[持续更新中…]

    一.概述 RESTful Web API [Web标准篇]RESTful Web API [设计篇] 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用 二.路由 ...

  7. 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?

    在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持, ...

  8. 《ASP.NET Web API 2框架揭秘》样章(PDF版本)

    <ASP.NET Web API 2框架揭秘>(详情请见<新作<ASP.NET Web API 2框架揭秘>正式出版>)以实例演示的方式介绍了很多与ASP.NET ...

  9. 新作《ASP.NET Web API 2框架揭秘》正式出版

    我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西.对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠.如果我们将整个“ ...

随机推荐

  1. 微信JSSDK分享功能实现

    <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <scri ...

  2. Java 创建线程的方法

    为了偷懒少敲几个字这里我写了一个Util类: package test; public class Util { static void println() {System.out.println() ...

  3. Linux命令之useradd

    useradd [选项] LOGIN(登录名) useradd –D useradd –D [选项] 创建一个新用户或更新默认新用户信息.useradd和adduser命令相同,adduser是use ...

  4. [Codeforces #174] Tutorial

    Link: Codeforces #174 传送门 A: 求原根的个数,有一条性质是原根个数为$\phi(\phi(n))$,多了一个不会证的性质 如果要确定哪些是原根的话还是要枚举,不过对于每个数不 ...

  5. 【Splay】Codeforces Round #424 (Div. 1, rated, based on VK Cup Finals) B. Cards Sorting

    Splay要支持找最左侧的最小值所在的位置.类似线段树一样处理一下,如果左子树最小值等于全局最小值,就查左子树:否则如果当前节点等于全局最小值,就查当前节点:否则查右子树. 为了统计答案,当然还得维护 ...

  6. 【高斯消元】BZOJ1013-[JSOI2008]球形空间产生器sphere

    [题目大意] 给出n维空间中给出n+1个点的坐标,求出球心坐标. [思路] 令球心坐标为x1,x2...xn,假设当前第i个点坐标为a1,a2...,an,第i+1个点坐标为b1,b2...,bn,则 ...

  7. JavaScript之引用类型(Object类型)

    ECMAScript提供了很多原生的引用类型,以便开发人员进行常见的计算任务. 对象是某一个特定引用类型的的实例. Object类型 用的最多.虽然这个Object实例不具备多少功能,但是在应用程序的 ...

  8. ES6 标签模板

    标签模板其实不是模板,而是函数调用的一种特殊形式."标签"指的是函数,紧跟在后面的模板字符串就是它的参数. var a = 5; var b = 10; tag `Hello ${ ...

  9. 手Q游戏中心上线 完美释放娱乐基因

        今年A股市场上手游概念股的表现可谓“独当一面”,不少和手游沾边的公司股价都翻了倍.在笔者看来,这些手游企业的股价明显高得离谱,这轮行情可以证明资本市场对手游的关注度非常高,但并不意味着这些手游 ...

  10. 从co到koa01-co

    thunk 他的发展是由函数的求值策略的分歧决定的,两种求值策略 传值调用,在进入函数体之前就直接执行完,把值传进去 传名调用,将表达式传入函数体,只在用到他的时候求值 传名函数的编译器实现,其实就是 ...