mvc5中webapi的路由

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

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類型web

對應MapHttpRoute方法api

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方法mvc

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類型ide

//2.把路由加入HostedHttpRouteCollection中routes.Add方法函數

public override void Add(string name, IHttpRoute route)
        {
            this._routeCollection.Add(name, route.ToRoute());
        }

從參數第4步可知_routeCollection爲全局變量RouteTable.Routes中this

因此webapi中路由的註冊實際最後也是註冊到RouteTable.Routes全局變量中url

3.webapi的routehandler

根據前邊可知webapi的路由最後同mvc同樣都是註冊到全局路由變量中,在路由中經過urlRoutingModule獲取請求而後轉發到對應的handler中,那麼webapi對應的routehandler是什麼呢?spa

(1).從註冊的單個路由類HostedHttpRoute中

從註冊路由的maphttpRoute方法中code

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;
        }
View Code

傳入的handler參數都爲nullblog

在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.

相關文章
相關標籤/搜索