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 ...
随机推荐
- 【百度地图API】建立全国银行位置查询系统(一)——如何创建地图
原文:[百度地图API]建立全国银行位置查询系统(一)--如何创建地图 <摘要>你将在第一章中学会以下知识: 如何创建一个网页文件 怎样利用百度地图API建立一张2D地图,以及3D地图 如 ...
- E: 无法获取锁 /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)解决方法
/********************************************************************* * Author : Samson * Date ...
- AngularJS之使用控制器封装业务逻辑
AngularJS之使用控制器封装业务逻辑 控制器的作用 我们知道,在AngularJS中,实现数据绑定的核心是scope对象.那么控制器又有什么用呢? 简单地说,没有控制器/controller,我 ...
- JavaScript中,关于new的那些事
这篇文章是自己对new学习过程中的一些理解,有不对的地方希望指出,接受组织的批评教育. 导火线,前段时间学习jQuery的时候,看到源码中有这样一段: jQuery = function(select ...
- 怎样使Android应用程序获得root权限
Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 写这篇文章前,首先要感谢 Simon_fu ,他的两篇关于 root 权 ...
- java23种设计模式详解(转)
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- <<Python基础课程>>学习笔记 | 文章13章 | 数据库支持
备注:本章介绍了比较简单,只是比较使用样品,主要假设是把握连接,利用数据库.和SQLite做演示样本 ------ Python数据库API 为了解决Python中各种数据库模块间的兼容问题,如今已经 ...
- 从.net复制源代码中国农历阵列,必要做日历
从.net复制源代码中国农历阵列,必要做日历 const { 闰月的月份.春节的阳历日期(农历正月初一).农历的每一个月天数 } c_arrLunarInfo: array [1900 .. 2100 ...
- 搭建环境Visual Studio 2013 社区版
搭建环境Visual Studio 2013 社区版 ActiveReports 9刚刚发布3天,微软就发布了 Visual Studio Community 2013 开发环境. Visual St ...
- [译]Java 设计模式之工厂
(文章翻译自Java Design Pattern: Factory) 1.Java工厂模式的来历 工厂设计模式用于创建基于不同参数的对象.下面的例子就是在一个工厂里创建一个人.如果我们向工厂要一个b ...