我们在开发完Asp.Net WebAPI程序后,可以使用WebHost寄宿方式或者SelfHost寄宿方式来部署Asp.Net WebAPI。所谓WebHost寄宿就是通过Asp.Net来实现;所谓SelfHost就是可以通过控制台、WinForm、WPF等方式寄宿。下面我们通过简单的例子来看看WebHost方式和SelfHost方式。

该Demo中包含一个类库项目、一个控制台项目以及一个空的WebForm项目。其中类库项目有一个继承自ApiController的名为HomeController的类;控制台项目实现SelfHost;WebForm项目实现WebHost:

WebAPI代码:

    public class HomeController : ApiController
{
public string Get(string fromStr)
{
return $"The request is from {fromStr}";
}
}

WebHost寄宿方式:

WebHost项目的Global文件代码:

    public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
GlobalConfiguration.Configuration.Routes.MapHttpRoute(name: "default", routeTemplate: "api/{controller}/{fromStr}");
}
}

启动运行WebHost项目,浏览器输入地址http://localhost:34827/api/home/webhost:

SelfHost寄宿方式:

SelfHost项目中的Program文件代码:

        static void Main(string[] args)
{
Assembly.Load("WebAPI,Version=1.0.0.1,Culture=neutral,PublicKeyToken=null"); HttpSelfHostConfiguration configuration = new HttpSelfHostConfiguration("http://localhost:34827/");
using (HttpSelfHostServer server = new HttpSelfHostServer(configuration))
{
server.Configuration.Routes.MapHttpRoute(name: "default", routeTemplate: "api/{controller}/{fromStr}");
server.OpenAsync(); Console.Read();
}
}

启动运行SelfHost项目,浏览器输入地址http://localhost:34827/api/home/from_selfhost:

从上面的例子可以看到Asp.Net WebAPI可以有多重寄宿方式,而Asp.Net WebAPI可以实现多种寄宿方式的原因在于:Asp.Net WebAPI有一个独立于寄宿环境的抽象管道,这个抽象管道是Asp.Net WebAPI的消息处理管道。

下面正式进入今天的主题:Asp.Net WebAPI消息处理管道。Asp.Net WebAPI的消息处理管道是一组HttpMessageHandler的有序组合。在这个消息处理管道中,除了最后一个HttpMessageHandler外,其他的都是由DelegatingHandler这个类型组成的委托链,最后一个HttpMessageHandler是最终处理请求(查找Controller、执行Action)的地方。下面我们通过翻看源码来看看组成消息处理管道的这个有序组合都是哪些类型:

在了解完组成Asp.NetWebAPI消息处理管道的类型后,我们通过一个例子来看看是怎么组成的。我们改一下前面的例子,在WebAPI项目中添加两个自定义的HttpMessageHandler和自定义的HttpServer作为“龙头”:

    public class MyHttpMessageHanlder1 : DelegatingHandler
{
} public class MyHttpMessageHanlder2 : DelegatingHandler
{
} public class MyHttpServer:HttpServer
{
public MyHttpServer(HttpConfiguration configuration):base(configuration)
{ } public new void Initialize()
{
base.Initialize();
}
}

修改HomeController的代码:

    public class HomeController : ApiController
{
public Tuple<IEnumerable<string>, IEnumerable<string>> Get(string fromStr)
{
HttpConfiguration configuration = new HttpConfiguration();
configuration.MessageHandlers.Add(new MyHttpMessageHanlder1());
configuration.MessageHandlers.Add(new MyHttpMessageHanlder1()); MyHttpServer server = new MyHttpServer(configuration); IEnumerable<string> handler1 = GetHandlers(server).ToArray();
server.Initialize();
IEnumerable<string> handler2 = GetHandlers(server).ToArray(); return new Tuple<IEnumerable<string>, IEnumerable<string>>(handler1, handler2);
} private IEnumerable<string> GetHandlers(DelegatingHandler handler)
{
yield return handler.GetType().Name;
while (handler.InnerHandler != null)
{
yield return handler.InnerHandler.GetType().Name;
handler = handler.InnerHandler as DelegatingHandler;
if (handler == null)
break;
}
}
}

运行程序后输入地址http://localhost:34827/api/home/from:

由上面的例子,我们验证了HttpServer为消息处理管道的“龙头”,HttpRoutingDispatcher为管道的“龙尾”,我们自定义的委托链接点是保存在HttpConfiguration类型的MessageHanlers属性中,在HttpServer调用Initialize方法时把MessageHandlers中的委托链节点和“龙头”、“龙尾”组成一个消息处理管道委托链。

通过上面的实例我们知道了组成Asp.Net WebAPI消息处理管道的类型和验证了Asp.Net WebAPI消息处理管道的创建,下面我们继续看看作为消息处理管道的“龙头”和“龙尾”内部都做了些什么。

当请求流转到消息处理管道的最后一个节点时,通过源码,如下,我们可以看到在最后的节点中完成的动作是:根据RouteData找到对应的Controller和Action,然后执行Action,将得到的响应数据逆序流转到“龙头”HttpServer中,在有HttpServer返回给客户端。

总结:

通过前面的剖析,我们知道Asp.Net WebAPI有多种寄宿方式,是因为它有一个独立于寄宿环境的消息处理管道,然后我们也对组成Asp.Net WebAPI消息处理管道的各种类型进行了剖析,并从中发现了消息处理管道是如何创建、请求是如何在管道中流转以及各个管道的作用。

至此,我们对Asp.Net WebAPI消息处理管道进行了一个简单的剖析,由于个人能力有限,如有不对,欢迎指正。

最新文章

  1. mybatis高级(1)(入门回顾)
  2. win 7,win2008 无法给新建用户完全权限
  3. 【C语言入门教程】4.2 二维数组
  4. oracle 语句 字段拼接(可换行)
  5. 2016年12月7日 星期三 --出埃及记 Exodus 21:2
  6. Cubietruck查看CPU及硬盘温度
  7. [算法练习] UVA 10420 - List of Conquests?
  8. [转] C# Winform 拦截关闭按钮触发的事件
  9. 测试工具:insure++
  10. grub2与grub区别
  11. android自定义view之---组合view
  12. jquery瀑布流排列样式代码
  13. 249. Group Shifted Strings把迁移后相同的字符串集合起来
  14. Maven的课堂笔记1
  15. tarfile — Read and write tar archive files
  16. python调用C++之pybind11入门(相互调用)
  17. 有关jQuery valid 验证多个同name属性的input的问题
  18. java泛型之泛型边界
  19. JavaSE复习(二)集合
  20. UNDO表空间损坏导致数据库无法OPEN

热门文章

  1. IIS Default Web Site : The service did not response to the start or control request in a timely fashion
  2. iOS开发——UIImageView
  3. iOS8 UISearchViewController搜索功能讲解
  4. 利用jackson转成json字符串(ssh中)
  5. 安卓 listview与arrayadapter
  6. 【转】IntentService的原理及使用
  7. java名词解释,让你更好理解
  8. http://begin.lydsy.com/JudgeOnline/problem.php?id=2770(PKU2503 Babelfish)
  9. iOS 之 通知
  10. [ Android 五种数据存储方式之四 ] —— ContentProvider存储数据