目录

  1. HttpMessageHandler

  2. Web Host模式处理过程

  3. Self Host模式处理过程

HttpMessageHandler

Web API处理管道由一系列HttpMessageHandler组成

public abstract class HttpMessageHandler : IDisposable
{
protected internal abstract Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken); protected virtual void Dispose(bool disposing) public void Dispose()
}

而一般在管道中,我们使用DelegatingHandler

public abstract class DelegatingHandler : HttpMessageHandler
{
public HttpMessageHandler InnerHandler { get; set; }
protected internal override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return this.innerHandler.SendAsync(request, cancellationToken);
}
}

头部是HttpServer

public class HttpServer : DelegatingHandler
{
public HttpMessageHandler Dispatcher { get; }
public HttpConfiguration Configuration { get; }
protected virtual void Initialize()
{
this.InnerHandler = HttpClientFactory.CreatePipeline(this._dispatcher, (IEnumerable<DelegatingHandler>) this._configuration.MessageHandlers);
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
this.EnsureInitialized();
return await base.SendAsync(request, cancellationToken);
}
}

其中Dispatcher就是管道的尾部

默认为HttpRoutingDispatcher

public class HttpRoutingDispatcher : HttpMessageHandler
{
public HttpConfiguration Configuration { get; }
private readonly HttpMessageInvoker _defaultInvoker = new HttpControllerDispatcher(configuration); public HttpRoutingDispatcher(HttpConfiguration configuration, HttpMessageHandler defaultHandler) protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
//1. Routing
IHttpRouteData routeData = request.GetRouteData();
if (routeData == null)
{
routeData = this._configuration.Routes.GetRouteData(request);
if (routeData != null)
request.SetRouteData(routeData);
}
//2. Dispatcher
this._defaultInvoker.SendAsync(request, cancellationToken);
}
}

实现Dispatcher(选择IHttpController)的对象默认为HttpControllerDispatcher

public class HttpControllerDispatcher : HttpMessageHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpControllerDescriptor controllerDescriptor = this.ControllerSelector.SelectController(request);
IHttpController controller = controllerDescriptor.CreateController(request);
return await controller.ExecuteAsync(controllerContext, cancellationToken);
}
}

验证管道

public class DemoController : ApiController
{
public IEnumerable<string> Get()
{
var cfg = new HttpConfiguration();
cfg.MessageHandlers.Add(new Handler1());
cfg.MessageHandlers.Add(new Handler1());
cfg.MessageHandlers.Add(new Handler1());
var server = new MyServer(cfg);
server.Initialize();//生成HttpMessageHandler链
return GetHandlers(server);
} private IEnumerable<string> GetHandlers(MyServer server)
{
DelegatingHandler next = server;
yield return next.ToString();
while (next.InnerHandler != null)
{
yield return next.InnerHandler.ToString();
next = next.InnerHandler as DelegatingHandler;
if (next == null)
break;
}
}
}
class MyServer : HttpServer
{
public MyServer(HttpConfiguration cfg) : base(cfg) { } public new void Initialize()//暴露Initialize方法
{
base.Initialize();
}
}
class Handler1 : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}

浏览器中请求:

Web Host模式处理过程

上节我们说到HttpControllerHandler为Web Host下的处理程序.

public class HttpControllerHandler : HttpTaskAsyncHandler
{
private readonly HttpMessageInvoker _server = GlobalConfiguration.DefaultServer; public override Task ProcessRequestAsync(HttpContext context)
{
response = await this._server.SendAsync(request, cancellationToken);
await response.Content.CopyToAsync(context.Response.OutputStream);
}
}

从上面的代码中我们看到

  1. HttpControllerHandler实现的是异步HttpControllerHandler接口

  2. 在ProcessRequestAsync方法中 通过GlobalConfiguration.DefaultServer 启动了WebAPI管道

Self Host模式处理过程

Self Host目前可以说分为2种

  1. OWIN
  2. HttpBinding

本节重点说明一下传统方式的HttpBinding,WebAPI使用的Message为HttpMessage

通过Nuget可以非常方便的操作

Install-Package Microsoft.AspNet.WebApi.SelfHost

using (var server = new HttpSelfHostServer(new HttpSelfHostConfiguration("http://localhost:10000")))
{
server.Configuration.Routes.MapHttpRoute("default", "{controller}");
server.OpenAsync();
Console.Read();
}

接下来我们将定义一个HttpSelfHostServer来实现SelfHost

API是不是相比SelfHost更方便?

using (var server = new MyHttpSelfHostServer("http://localhost:10000"))
{
server.Configuration.Routes.MapHttpRoute("default", "{controller}");
server.OpenAsync();
Console.Read();
}

再看看我们具体的MyHttpSelfHostServer如何实现

public class MyHttpSelfHostServer : HttpServer
{
private string _url;
public MyHttpSelfHostServer(string url)
{
_url = url;
} public async void OpenAsync()
{
var binding = new HttpBinding();
var listener = binding.BuildChannelListener<IReplyChannel>(new Uri(_url));
listener.Open();//开启监听
var reply = listener.AcceptChannel();
reply.Open();//开启通信通道
while (true)
{
var request = reply.ReceiveRequest();//接受到请求
//获取HttpRequestMessage
var method = request.RequestMessage.GetType().GetMethod("GetHttpRequestMessage");
var requestMessage = method.Invoke(request.RequestMessage, new object[] { true }) as HttpRequestMessage;
var response = await base.SendAsync(requestMessage, new CancellationTokenSource().Token);
request.Reply(CreateMessage(response));//回复消息
}
} Message CreateMessage(HttpResponseMessage response)
{
var type = Type.GetType("System.Web.Http.SelfHost.Channels.HttpMessage,System.Web.Http.SelfHost");
return (Message)Activator.CreateInstance(type, response);
}
}

最后我们来请求一下地址:http://localhost:10000/Demo

备注:

  • 文章中的代码并非完整,一般是经过自己精简后的.

  • 本篇内容使用MarkDown语法编辑

首发地址:http://neverc.cnblogs.com/p/5949974.html

[Web API] Web API 2 深入系列(2) 消息管道的更多相关文章

  1. ASP.NET Web API - ASP.NET MVC 4 系列

           Web API 项目是 Windows 通信接口(Windows Communication Foundation,WCF)团队及其用户激情下的产物,他们想与 HTTP 深度整合.WCF ...

  2. 如何用Baas快速在腾讯云上开发小程序-系列1:搭建API & WEB WebSocket 服务器

    版权声明:本文由贺嘉 原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/221059001487422606 来源:腾云阁 h ...

  3. Java web与web gis学习笔记(二)——百度地图API调用

    系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...

  4. HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)

    1.Web Storage HTML5除了Canvas元素之外,还有一个非常重要的功能那就是客户端本地保存数据的Web Storage功能. 以前都是用cookies保存用户名等简单信息.   但是c ...

  5. 我所理解的RESTful Web API [Web标准篇]

    REST不是一个标准,而是一种软件应用架构风格.基于SOAP的Web服务采用RPC架构,如果说RPC是一种面向操作的架构风格,而REST则是一种面向资源的架构风格.REST是目前业界更为推崇的构建新一 ...

  6. 重构Web Api程序(Api Controller和Entity)续篇

    昨天有写总结<重构Web Api程序(Api Controller和Entity)>http://www.cnblogs.com/insus/p/4350111.html,把一些数据交换的 ...

  7. web api写api接口时返回

    web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...

  8. Google Maps API Web Services

    原文:Google Maps API Web Services 摘自:https://developers.google.com/maps/documentation/webservices/ Goo ...

  9. asp.net web api 构建api帮助文档

    1 概要 创建ASP.NET Web Api 时模板自带Help Pages框架. 2 问题 1)使用VS创建Web Api项目时,模板将Help Pages框架自动集成到其中,使得Web Api项目 ...

随机推荐

  1. Java实现文件在某个目录的检索

    package com.filetest; import java.io.File; import java.util.Date; import java.util.Scanner; public c ...

  2. Hbuilder开发HTML5 APP之WebView

    WebView就是原生的WebView,HBuilder在其上封装了一层,便于Javascript的调用,结构如图: 也可以实现这样的结构: 注意:WebView的使用属性HTML5+规范,所以必须等 ...

  3. IOS第二天-新浪微博 - 添加搜索框,弹出下拉菜单 ,代理的使用 ,HWTabBar.h(自定义TabBar)

    ********HWDiscoverViewController.m(发现) - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框对象 HWSearc ...

  4. ASP.NET安全

    ASP.NET 安全 概述 安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问题.本篇主要包括以下几个内容 : 认证 授权 ...

  5. Kruskal 最小生成树算法

    对于一个给定的连通的无向图 G = (V, E),希望找到一个无回路的子集 T,T 是 E 的子集,它连接了所有的顶点,且其权值之和为最小. 因为 T 无回路且连接所有的顶点,所以它必然是一棵树,称为 ...

  6. 【VC++技术杂谈007】使用GDI+进行图片格式转换

    本文主要介绍如何使用GDI+对图片进行格式转换,可以转换的图片格式为bmp.jpg.png. 1.加载GDI+库 GDI+是GDI图形库的一个增强版本,提供了一系列Visual C++ API.为了使 ...

  7. AngularJS2 + ASP.NET MVC项目

    环境:VS2015, NodeJS:v 6.5, npm: v3.10, AngularJs 2 通过将ASP.NET MVC项目与Angualr 2官网上的quick start整合的过程中遇到些问 ...

  8. 拓展 Android 原生 CountDownTimer 倒计时

    拓展 Android 原生 CountDownTimer 倒计时 [TOC] CountDownTimer 在系统的CountDownTimer上进行的修改,主要是拓展了功能,当然也保留了系统默认的模 ...

  9. android 获取屏幕宽度和高度

    // 获取屏幕宽高(方法1) int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480p ...

  10. 实战MEF(1):一种不错的扩展方式

    在过去,我们完成一套应用程序后,如果后面对其功能进行了扩展或修整,往往需要重新编译代码生成新的应用程序,然后再覆盖原来的程序.这样的扩展方式对于较小的或者不经常扩展和更新的应用程序来说是可以接受的,而 ...