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管道[上篇]的更多相关文章

  1. ASP.NET Web API的消息处理管道: Self Host下的消息处理管道[上篇]

    ASP.NET Web API的消息处理管道: Self Host下的消息处理管道[上篇] ASP.NET Web API服务端框架核心是一个独立于具体寄宿环境的消息处理管道,它不关心请求消息来源于何 ...

  2. ASP.NET WebAPI 06 HttpMessageHandler管道

    HttpMessageHandler管道 在Web API的中,微软为了更好的进行架构扩展,采用的了一套管道设计----HttpMessageHander(其实WCF也有类似架构). 在整个管道中的头 ...

  3. 【干货】.NET WebApi HttpMessageHandler管道

    消息拦截器是一个类,接收 HTTP request并返回 HTTP response,Message handler 继承自抽象类 HttpMessageHandler,那么学习消息过滤器之前你应该了 ...

  4. ASP.NET WebAPI 14 仿写Filter管道

    WebAPI中有设计了几种管道(Channel),大概如下:HttpMessageHandler,ActionFilter管道,ExceptionFilter管道.在三种管道中HttpMessageH ...

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

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

  6. ASP.NET Web API 2框架揭秘

    ASP.NET Web API 2框架揭秘(.NET领域再现力作顶级专家精讲微软全新轻量级通信平台) 蒋金楠 著   ISBN 978-7-121-23536-8 2014年7月出版 定价:108.0 ...

  7. 《ASP.NET Web API 2框架揭秘》

    <ASP.NET Web API 2框架揭秘> 基本信息 作者: 蒋金楠 出版社:电子工业出版社 ISBN:9787121235368 上架时间:2014-7-5 出版日期:2014 年7 ...

  8. asp.net web api 2框架揭秘文摘

    第一章 概述 URI 统一资源标识符 URL 统一资源定位符 http方法:get,post,put,delete,head等 状态码:100-199,请求已被接受: 200-299,成功状态: 30 ...

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

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

随机推荐

  1. 浏览器扩展系列————异步可插入协议(pluggable protocol)的实现

    原文:浏览器扩展系列----异步可插入协议(pluggable protocol)的实现 IE中有很多我们比较熟悉的协议,如http,https,mailto,ftp等.当然你也可以实现自己定义的协议 ...

  2. 2299 Ultra-QuickSort(归并)

    合并排序第一次.连环画看着合并看着别人的博客的想法. http://poj.org/problem? id=2299 #include <stdio.h> #include <std ...

  3. The Swift Programming Language-官方教程精译Swift(4)字符串和字符

    String 是一个有序的字符集合,例如 "hello, world", "albatross".Swift 字符串通过 String 类型来表示,也可以表示为 ...

  4. Entity Framework查询原理

    Entity Framework查询原理 前言 Entity Framework的全称是ADO.NET Entity Framework,是微软开发的基于ADO.NET的ORM(Object/Rela ...

  5. 一个简单的创建dom的函数

    var  regName = /^(div|a|p|ul|li|input|select|document|body|iframe)$/;function createDom(name, obj) { ...

  6. YII相关资料(干货)

    Sites 网站 yiifeed:Yii 最新动态都在这里 yiigist:Yii 专用的 Packages my-yii:Yii 学习资料和新闻 Docs 文档 Yii Framework 2.0 ...

  7. POJ 2553 The Bottom of a Graph (强连通分量)

    题目地址:POJ 2553 题目意思不好理解.题意是:G图中从v可达的全部点w,也都能够达到v,这种v称为sink.然后升序输出全部的sink. 对于一个强连通分量来说,全部的点都符合这一条件,可是假 ...

  8. Linux:最终用途cat命令查看不可见的字符

    常,的程序或软件,并没有语法错误,你检查其内容没有发现相关问题.这是时间,因为你用普通的文本编辑软件来查看,有很多的字符显示不出来的,但在最终用途cat命令可以很easy地检測出是否存在这些字符. ~ ...

  9. 基于4.5Framework web程序、SQLSERVER数据库打包

    原文:基于4.5Framework web程序.SQLSERVER数据库打包 估计很多朋友和我一样,对于C/S程序打包很熟悉,但对于B/S程序打包一头雾水... 最近公司要求我们把项目和数据库(SQL ...

  10. 对于发Github的contributions贡献不会增加

    最近发现每天在 Github 做代码提交,可是 contributions 的面板(贡献图)上的绿点(即贡献值)却没有增长了.擦~ 有两个礼拜了. 例如以下图并且.同一时候发现曾经的绿点也是稀稀拉拉的 ...