1.Global.asax中路由的注冊


public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas();
//api路由注冊 GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } }
2.GlobalConfiguration源碼
public static void Configure(Action<HttpConfiguration> configurationCallback) { if (configurationCallback == null) { throw new ArgumentNullException("configurationCallback"); }
//執行WebApiConfig.Register方法並傳入參數GlobalConfiguration.Configuration configurationCallback(GlobalConfiguration.Configuration); GlobalConfiguration.Configuration.EnsureInitialized(); }
(1)參數GlobalConfiguration.Configuration
1.public static HttpConfiguration Configuration { get { return GlobalConfiguration._configuration.Value; } } 2.private static Lazy<HttpConfiguration> _configuration = GlobalConfiguration.CreateConfiguration(); 3.private static Lazy<HttpConfiguration> CreateConfiguration() { Func<HttpConfiguration> arg_1F_0; if ((arg_1F_0 = GlobalConfiguration.<>c.<>9__11_0) == null) { arg_1F_0 = (GlobalConfiguration.<>c.<>9__11_0 = new Func<HttpConfiguration>(GlobalConfiguration.<>c.<>9.<CreateConfiguration>b__11_0)); } return new Lazy<HttpConfiguration>(arg_1F_0); } 4.[CompilerGenerated] [Serializable] private sealed class <>c { public static readonly GlobalConfiguration.<>c <>9 = new GlobalConfiguration.<>c(); ....internal HttpConfiguration <CreateConfiguration>b__11_0() {
//RouteTable.Routes全局路由變量 HttpConfiguration expr_0F = new HttpConfiguration(new HostedHttpRouteCollection(RouteTable.Routes)); ServicesContainer services = expr_0F.Services; services.Replace(typeof(IAssembliesResolver), new WebHostAssembliesResolver()); services.Replace(typeof(IHttpControllerTypeResolver), new WebHostHttpControllerTypeResolver()); services.Replace(typeof(IHostBufferPolicySelector), new WebHostBufferPolicySelector()); services.Replace(typeof(IExceptionHandler), new WebHostExceptionHandler(services.GetExceptionHandler())); return expr_0F; } }
(2)WebApiConfig.Register方法
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服務 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
由參數可知config.Routes為HostedHttpRouteCollection類型
對應MapHttpRoute方法
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler) { if (routes == null) { throw Error.ArgumentNull("routes"); } HttpRouteValueDictionary defaults2 = new HttpRouteValueDictionary(defaults); HttpRouteValueDictionary constraints2 = new HttpRouteValueDictionary(constraints);
//1.封裝單個路由 IHttpRoute httpRoute = routes.CreateRoute(routeTemplate, defaults2, constraints2, null, handler);
//2.把路由加入HostedHttpRouteCollection中
routes.Add(name, httpRoute); return httpRoute; }
//1.封裝單個路由 routes.CreateRoute方法
public override IHttpRoute CreateRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler) { if (constraints != null) { foreach (KeyValuePair<string, object> current in constraints) { this.ValidateConstraint(uriTemplate, current.Key, current.Value); } } return new HostedHttpRoute(uriTemplate, defaults, constraints, dataTokens, handler); }
可知HostedHttpRouteCollection中類型為HostedHttpRoute類型
//2.把路由加入HostedHttpRouteCollection中routes.Add方法
public override void Add(string name, IHttpRoute route) { this._routeCollection.Add(name, route.ToRoute()); }
從參數第4步可知_routeCollection為全局變量RouteTable.Routes中
所以webapi中路由的注冊實際最后也是注冊到RouteTable.Routes全局變量中
3.webapi的routehandler
根據前邊可知webapi的路由最后同mvc一樣都是注冊到全局路由變量中,在路由中通過urlRoutingModule獲取請求然后轉發到對應的handler中,那么webapi對應的routehandler是什么呢?
(1).從注冊的單個路由類HostedHttpRoute中
從注冊路由的maphttpRoute方法中

public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults) { return routes.MapHttpRoute(name, routeTemplate, defaults, null, null); } public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints) { return routes.MapHttpRoute(name, routeTemplate, defaults, constraints, null); } public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler) { if (routes == null) { throw Error.ArgumentNull("routes"); } HttpRouteValueDictionary defaults2 = new HttpRouteValueDictionary(defaults); HttpRouteValueDictionary constraints2 = new HttpRouteValueDictionary(constraints); IHttpRoute httpRoute = routes.CreateRoute(routeTemplate, defaults2, constraints2, null, handler); routes.Add(name, httpRoute); return httpRoute; }
傳入的handler參數都為null
在routes.CreateRoute方法中生成HostedHttpRoute調用構造函數時傳入的也是null
public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
{
.....
//1.封裝單個路由
IHttpRoute httpRoute = routes.CreateRoute(routeTemplate, defaults2, constraints2, null, handler);
.....
}
public override IHttpRoute CreateRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler)
{
.......
return new HostedHttpRoute(uriTemplate, defaults, constraints, dataTokens, handler);
}
HostedHttpRoute的構造函數
public HostedHttpRoute(string uriTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, HttpMessageHandler handler) { RouteValueDictionary defaults2 = (defaults != null) ? new RouteValueDictionary(defaults) : null; RouteValueDictionary constraints2 = (constraints != null) ? new RouteValueDictionary(constraints) : null; RouteValueDictionary dataTokens2 = (dataTokens != null) ? new RouteValueDictionary(dataTokens) : null; this.OriginalRoute = new HttpWebRoute(uriTemplate, defaults2, constraints2, dataTokens2, HttpControllerRouteHandler.Instance, this); this.Handler = handler; }
hostedHttpRoute中的getdata通過調用OriginalRoute屬性獲取對應的routedata.
綜上:webapi對應的routehandler為HttpControllerRouteHandler
可知:webapi對應的routehandler為httpControllerRouteHandler
4 webapi對應的handler
從httpControllerRouteHandler中
protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) { return new HttpControllerHandler(requestContext.RouteData); }
獲得HttpControllerHandler.