剖析Asp.Net Web API路由系统---WebHost部署方式
上一篇我们剖析了asp.net路由系统,今天我们再来简单剖析一下asp.net web api以webhost方式部署时,asp.net web api的路由系统内部是怎样实现的。还是以一个简单实例开头。
创建一个空的webapi项目,在global中注册路由信息:
public class webapiapplication : system.web.httpapplication { protected void application_start() { //注册路由 globalconfiguration.configuration.routes.maphttproute( name: "default", routetemplate: "api/{controller}/{id}", defaults: new { id = routeparameter.optional }); } }
创建一个名为home的controller:
public class homecontroller : apicontroller { // get: api/home public ienumerable<string> get() { return new string[] { "value1", "value2" }; } // get: api/home/5 public string get(int id) { return "value"; } }
启动运行,在浏览器地址栏分别输入http://localhost:46351/api/home和http://localhost:46351/api/home/5,结果如下:
简单看了一下asp.net web api的实例,下面我们开始剖析asp.net web api的路由系统。
首先看一下在asp.net web api中路由的注册方式,如下:
在这个路由注册过程中,隐藏了哪些操作呢?下面我们源码:
通过翻看源码可以看到,asp.net web api中路由的注册实际上是通过调用httproutecollection类型的扩展方法maphttproute实现的,在maphttproute方法里面,我们看到创建的路由对象通过调用httproutecollection对象的add方法保存了。而由于globalconfiguration的静态属性通过configuration是hostedhttproutecollection类型以routetable.routes为构造参数创建的,又因为hostedhttproutecollection类型是httproutecollection类型的子类,在hostedhttproutecollection类型中,子类hostedhttproutecollection重写了父类型的add方法和createroute方法,如下图,所以,实际上创建出来的路由对象的类型为hostedhttproute,此路由对象放到全局路由表中保存了,从这里我们可以知道,保存到全局路由表中的路由对象的类型为hostedhttproute。那么,注册的路由对象放到全局路由表中保存有什么用呢,后续部分分析。
从上面源码可以看到,最后创建的路由对象是hostedhttproute类型,那么现在有个问题,我们在前面注册路由的时候,并没有指定routehandler和httphandler,它们是从哪里添加到路由对象中的呢?在创建hostedhttproute对象的过程中,又有哪些隐藏的秘密呢?我们下面继续查看源码:
通过上文的剖析,到目前为止,我们可以知道在asp.net web api以webhost方式寄宿时,注册的路由对象为hostedhttproute类型的实例,保存在全局路由表routetable.routes中,而用于处理请求的routehandler和httphandler分别为httpcontrollerroutehandler类型的实例和httpcontrollerhandler类型的实例。
注册完路由信息后,在asp.net web api中是如何利用注册的路由信息进行路由的呢?会不会也是跟asp.net中一样通过一个httpmodule来实现的呢,我们启动程序看一下global类中的modules属性:
从上面截图可以清楚看到,在asp.net web api以webhost方式寄宿服务时,也是跟asp.net一样,通过urlroutingmodule来实现路由的。从上一篇针对asp.net路由系统的剖析中,我们可以知道,asp.net是通过urlroutingmodule对请求进行拦截后,然后从全局路由表中依次进行匹配以获取与请求url匹配的routedata进行后续处理的。在asp.net web api中,从上文中我们知道了保存在全局路由表的路由对象是hostedhttproute类型的,下面我们继续剖析在asp.net web api中最终是怎么获取到匹配的routedata的。
在urlroutingmodule中,routedata是通过依次调用每个路由对象的getroutedata方法获取的。在asp.net web api中,由于路由对象的类型为hostedhttproute,下面我们来看看调用getroutedata方法时发生了什么:
可以看到,在hostedhttproute中是通过属性originalroute的getroutedata方法获取routedata的,由前文的剖析中,我们知道这个originalroute属性是httpwebroute类型:
从上面剖析中可以看到,asp.net web api以webhost方式部署时,最终还是通过asp.net的路由系统完成匹配工作。不过有一定需要注意的是,由于在httpwebroute中对父类型的验证约束的方法进行了重写,所以对于约束的验证,asp.net web api还是使用了自己的方式进行验证约束是否匹配:
最后,通过一系列的工作获取到了routedata对象和包含在里面的routehandler、httphandler后,asp.net web api就可以通过这些获取到的进行请求的处理和响应了。
总结:
通过上文的剖析,可以得出:在asp.net web api以webhost方式部署时,注册的路由是保存在全局路由表中的;在获取routedata时,是通过asp.net路由系统的匹配规则进行路由匹配的,不过却实现了自己的约束验证规则。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。