ASP.NET WEB API 2:生命周期底层原理详解二(HTTP Message Handlers)

ASP.NET WEB API 2:生命周期底层原理详解二(HTTP Message Handlers)

7915发表于2019-04-14


二、HTTP Message Handlers

一个特定的HttpRequestMessage,如果有一个DelegatingHandler的能够直接处理这种请求,则DelegatingHandler直接处理并返回一个HttpRequestResponse,下面的管道流程不会往下执行。DelegatingHandler会在下面详细介绍

如果没有DelegatingHandler能直接处理,则进行HttpRoutingDispatcher路由匹配处理,在此匹配上的路由会进行判断有没有单独设置Handler,如果有Handler则执行(Per-router流程)是一个自定义的Message Handlers。

如果该路由规则没有设置Handler,那么就进行HttpControllerDispatcher控制器Controller查找匹配处理,并创建匹配到的API Controller。

Http Message Handlers是Web API管道的第一个步骤,这个过程是传进来的HttpRequestMessage对象,最后出去的是HttpRequestResponse对象。

HttpRequestMessage和HttpRequestResponse当然不能单独的存在,它们两者是通过类HttpMessageHandler来建立关联的。

HttpMessageHandler是一个抽象类,它是HTTP message handlers的核心类,它的作用是处理请求并采用异步的方法来返回结果。

HttpMessageHandler类里面代码非常的直接和简单:

namespace System.Net.Http
{
  public abstract class HttpMessageHandler : IDisposable
  {
    protected HttpMessageHandler()
    {
      if (Logging.On)
        Logging.Enter(Logging.Http, (object) this, ".ctor", (string) null);
      if (!Logging.On)
        return;
      Logging.Exit(Logging.Http, (object) this, ".ctor", (string) null);
    }
 
    protected internal abstract Task<HttpResponseMessage>  
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
 
    protected virtual void Dispose(bool disposing)
    {
    }
 
    public void Dispose()
    {
      this.Dispose(true);
      GC.SuppressFinalize((object) this);
    }
  }
}
里面最重要的就是SendAsync方法,我们知道在.NET里面以Async结尾的方法一般都是异步方法,这个SendAsync方法是一个抽象方法而且是protected表明中只能其子类内部调用。


参数是HttpRequestMessage,返回值是Task<HttpResponseMessage>

前面我们说到HttpMessageHandler类是抽象的,而要实现Http Message Handle(Http消息处理),就要自己实现SendAsync方法里面的逻辑。

Web API框架为我们提供了一个默认的实现,类名叫DelegatingHandler,当然我们也可以自己实现一些如:DelegatingHandler1,DelegatingHandler2。

如果有多个DelegatingHandler的执行流程如下图:

以上就是DelegatingHandler管道流程,也叫做Russian Doll Model(俄罗斯娃娃模型),从上图可以看出管道里面会依次执行多个DelegatingHandler。这些都是DelegatingHandler的子类。

Http Message Handlers其实就是执行DelegatingHandler类的过程。DelegatingHandler主要作用是处理HttpRequestMessage或者HttpResponseMessage并把工作单元和控制传递给下一个DelegatingHandler。

此处用到了委托设计模式


DelegatingHandler类是也是一个抽象类,在命名空间System.Net.Http,它有一个重要的方法SendAsync,如下:

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);
}


可以看到执行完了自己的SendAsync方法的最后调用的innerHandler的SendAsync,而innerHandler是一个HttpMessageHandler类型的属性,它是通过构造函数传进来的:

protected DelegatingHandler(HttpMessageHandler innerHandler)
{
  this.InnerHandler = innerHandler;
}
 
public HttpMessageHandler InnerHandler
{
  get
  {
       return this.innerHandler;
  }
  set
  {
       if (value == null)
         throw new ArgumentNullException("value");
       this.CheckDisposedOrStarted();
       if (Logging.On)
         Logging.Associate(Logging.Http, (object) this, (object) value);
       this.innerHandler = value;
  }
}


下面我们来看看创建API Controler的详细过程:


我们可以从上面看到HttpControllerDispatcher有两个主要功能:

1、根据请求信息选择与之相关的Controller类型

2、激活步骤1中找到的Controller创建一个它的一个实例对象



小编蓝狐