mvc5中webapi的路由

Posted nnyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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类型

对应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;
        
View Code

传入的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.

以上是关于mvc5中webapi的路由的主要内容,如果未能解决你的问题,请参考以下文章

asp.net webapi 2属性路由不起作用

web api 2 路由 - 找不到资源

用MVC5+EF6+WebApi 做一个考试功能 前端主题

MVC 5 身份验证

ASP.NET MVC5 新特性:Attribute路由使用详解

IIS 7.5 上的 MVC5 路由错误 (404.0) 错误