HttpMessageHandler管道[上篇]
HttpMessageHandler管道[上篇]
整个ASP.NET Web API服务端框架采用管道式设计,这个用于“处理请求、响应回复”的管道本质上就是一组HttpMessageHandler的有序组合。这是一个“双向管道”,具有相反方向的请求消息和响应消息同时在这个管道中流动。对于与一个出于中间位置的HttpMessageHandler来说,当前一个HttpMessageHandler完成了对请求的处理之后,会将处理后的请求传递给自己。定义在自身的请求消息处理操作将直接作用于该请求消息之上,一旦处理完毕再将处理后的请求往后传递。对于反方向的响应消息的处理方式与此类似。[本文已经同步到《How ASP.NET Web API Works?》]
目录
一、HttpMessageHandler
二、DelegatingHandler
一、HttpMessageHandler
ASP.NET Web API服务端框架由一组HttpMessageHandler经过“首尾相连”而成,管道式设计使该框架具有很高的扩展性。虽然ASP.NET Web API服务端框架的作用是“处理请求、响应回复”,但是具体采用的处理策略因具体的场景而不同。我们不可能也没有必要创建一个“万能”的处理器来满足所有的请求处理场景,所以倒不如让某个处理器只负责某个单一的消息处理功能。针对具体的应用场景中,我们可以根据具体的消息处理需求来选择所需的处理器并共同组成一个完成的消息处理管道。在这里这个用于完成某个单一消息处理功能的处理器就是HttpMessageHandler。
这里的“消息处理”具有两个层面的含义,既包括针对请求消息的处理,还包括基于响应消息的处理。旨在实现某个单一消息处理功能的HttpMessageHandler直接或者间接继承自具有如下定义的抽象类型HttpMessageHandler。在前面介绍“URL路由”中,我们已经提到过ASP.NET Web API通过类型HttpRequestMessage和HttpResponseMessage分别表示管道处理的请求消息和响应消息,所以对HttpMessageHandler的定义就很好理解了。
1: public abstract class HttpMessageHandler : IDisposable
2: {
3: public void Dispose();
4: protected virtual void Dispose(bool disposing);
5:
6: protected abstract Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
7: }

如上面的代码片断所示,抽象类HttpMessageHandler中仅仅定义了一个唯一的受保护的抽象方法SendAsync,这是一个基于“并行编程(Paralle Programing)”而设计的异步方法。其request参数表示传递给当前HttpMessageHandler用于处理的请求消息,这是一个HttpRequestMessage对象。另一个参数cancellationToken是一个发送取消操作信号的CancellationToken对象,如果读者对.NET中的并行编程具有基本了解的话,相信对这个对象应该很熟悉。
针对请求消息和响应消息的处理同时体现在这个SendAsync方法上。具体来说,针对请求消息的处理直接实现在SendAsync方法中,而针对响应消息的处理则通过其返回值来完成,这是一个类型为Task<HttpResponseMessage>的对象。通过HttpMessageHandler组成的消息处理管道以及请求消息和响应消息在管道中的“流动”基本上可以通过右图体现出来。
抽象类HttpMessageHandler实现了IDisposable接口,它按照“标准”的方式实现Dispose方法。如下面的代码片断所示,调用Dispose方法被调用的时候,并没有执行任何资源回收操作。当我们通过继承这个抽象类自定义HttpMessagHandler的时候,可以通过重写这个受保护的虚方法来完成资源释放的相关操作。
1: public abstract class HttpMessageHandler : IDisposable
2: {
3: //其他操作
4: public void Dispose()
5: {
6: this.Dispose(true);
7: GC.SuppressFinalize(this);
8: }
9:
10: protected virtual void Dispose(bool disposing)
11: {}
12: }
二、DelegatingHandler

我们说ASP.NET Web API整个消息处理管道是通过一组有序的HttpMessagHandler“首尾相连”而成,具体实现“串联”的是通过DelegatingHandler这个类型来完成的。顾名思义,DelegatingHandler具有委托功能,当自己负责的任务完成之后可以委托第三方进行后续的工作。如果这个被委托者也是一个DelegatingHandler,不就可以组成一个委托链了吗?而这个委托链不就是一个个DelegatingHandler组成的消息处理管道吗?
如下面的代码片断所示,DelegatingHandler是一个继承自HttpMessageHandler类的抽象类。上面我们所说的这个被委托的第三方由它的属性InnerHandler表示,对应的类型为HttpMessageHandler(不是DelegatingHandler)。DelegatingHandler重写了定义在其类的抽象方法SendAsync,实际上除了直接调用InnerHandler属性的同名方法之外并没有完成任何实质性的操作。
1: public abstract class DelegatingHandler : HttpMessageHandler
2: {
3: protected internal override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
4: public HttpMessageHandler InnerHandler get; set; }
5: }
正如上面所说,如果ASP.NET Web API的消息处理管道均由DelegatingHandler组成(位于管道尾端的HttpMessageHandler除外),我们就可以根据其InnerHandler对另一个被委托的DelegatingHandler的引用,构成具有如右上图所示的链式结构。
HttpMessageHandler管道[上篇]的更多相关文章
- ASP.NET Web API的消息处理管道: Self Host下的消息处理管道[上篇]
ASP.NET Web API的消息处理管道: Self Host下的消息处理管道[上篇] ASP.NET Web API服务端框架核心是一个独立于具体寄宿环境的消息处理管道,它不关心请求消息来源于何 ...
- ASP.NET WebAPI 06 HttpMessageHandler管道
HttpMessageHandler管道 在Web API的中,微软为了更好的进行架构扩展,采用的了一套管道设计----HttpMessageHander(其实WCF也有类似架构). 在整个管道中的头 ...
- 【干货】.NET WebApi HttpMessageHandler管道
消息拦截器是一个类,接收 HTTP request并返回 HTTP response,Message handler 继承自抽象类 HttpMessageHandler,那么学习消息过滤器之前你应该了 ...
- ASP.NET WebAPI 14 仿写Filter管道
WebAPI中有设计了几种管道(Channel),大概如下:HttpMessageHandler,ActionFilter管道,ExceptionFilter管道.在三种管道中HttpMessageH ...
- 新作《ASP.NET Web API 2框架揭秘》正式出版
我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西.对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠.如果我们将整个“ ...
- ASP.NET Web API 2框架揭秘
ASP.NET Web API 2框架揭秘(.NET领域再现力作顶级专家精讲微软全新轻量级通信平台) 蒋金楠 著 ISBN 978-7-121-23536-8 2014年7月出版 定价:108.0 ...
- 《ASP.NET Web API 2框架揭秘》
<ASP.NET Web API 2框架揭秘> 基本信息 作者: 蒋金楠 出版社:电子工业出版社 ISBN:9787121235368 上架时间:2014-7-5 出版日期:2014 年7 ...
- asp.net web api 2框架揭秘文摘
第一章 概述 URI 统一资源标识符 URL 统一资源定位符 http方法:get,post,put,delete,head等 状态码:100-199,请求已被接受: 200-299,成功状态: 30 ...
- 总体介绍ASP.NET Web API下Controller的激活与释放流程
通过<ASP.NET Web API的Controller是如何被创建的?>我们已经对HttpController激活系统的核心对象有了深刻的了解,这些对象包括用于解析程序集和有效Http ...
随机推荐
- Android L下载
Android L千呼万唤最终出来了,那么我们先下载下来一睹为快,那么怎么去拿到最新的L的分支 那依照傻瓜步骤总结下(Linux Ubuntu) 1.获取repo文件 (1).curl https:/ ...
- SQL表连接
背景 在上次的自考科目<数据库系统原理>中.已经接触到了关于数据库表连接的一些知识,近期的学习过程中又用到了关于数据库表的连接问题,趁此再跟大家一起回想一下. 导图总结 首先用一张思维导图 ...
- 创建GitHub技术博客
创建GitHub技术博客全攻略 githubio技术博客网站生成 说明: 首先,你需要注册一个 github 账号,最好取一个有意义的名字,比如姓名全拼,昵称全拼,如果被占用,可以加上有意义的数字.本 ...
- Pku1218
<span style="background-color: rgb(204, 204, 204);">/* A - THE DRUNK JAILER Time Lim ...
- CI框架 .htaccess 隐藏url在index.php解决方案
CodeIgniter(下面简称"CI")是一款国外优秀的PHP轻量级MVC框架,它支持PHP4和PHP5.是开发中小型可拓展性需求高的Web应用程序的利器.眼下你所见到的这个博客 ...
- List<string>和string[]
List<string>和string[] List<string>是集合:string[]是数组: ///////////////////////////////////// ...
- Asterisk 未来之路3.0_0004
原文:Asterisk 未来之路3.0_0004 Asterisk Wiki asterisk 的Wiki是很多启迪和困惑的发源地,另外一个最重要的VOIP知识库www.voip-info.org ...
- Oracle中注意用户的访问权限
新增表.序列.存储过程等,要注意用户(例如System)的权限.如果在增删改查过程中出现数据库读写权限的报错,则在建表(或者序列.存储过程等)时,在脚本前面加 GRANT CREATE TABLE T ...
- C# 中参数验证方式
C# 中参数验证方式 一般在写方法的时候,第一步就是进行参数验证,这也体现了编码者的细心和缜密,但是在很多时候这个过程很枯燥和乏味,比如在拿到一个API设计文档的时候,通常会规定类型参数是否允许为空, ...
- javascript模仿块级作用域(第一篇)
作用域有词法作用域和块级作用域之分,javascript属于词法作用域,而在java.C++中却是块级作用域.在javascript中,只有函数能够创建作用域,作用域是以function作为边界的. ...