zoukankan      html  css  js  c++  java
  • 简说mvc路由

    首先我们通过在Global.asax中的Application_Start将路由信息注册到RouteTable的Routes静态属性中。如下代码所示: 

    public class RouteTable
    {
        //省略
        public static RouteCollection Routes { get; }
    }
    
    protected void Application_Start()
    {
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
    
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
    //MapRoute有多个重载,最终实例如下
    public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
    {
      //省略
        Route route = new Route(url, new MvcRouteHandler())
        {
            Defaults = CreateRouteValueDictionaryUncached(defaults),
            Constraints = CreateRouteValueDictionaryUncached(constraints),
            DataTokens = new RouteValueDictionary()
        };
    
        ConstraintValidation.Validate(route);
    
        if ((namespaces != null) && (namespaces.Length > 0))
        {
            route.DataTokens[RouteDataTokenKeys.Namespaces] = namespaces;
        }
    
        routes.Add(name, route);
    
        return route;
    }

     在new Route对象的同时,我们同时new了一个MvcRouteHandler对象实例传进去。然后将route添加到RouteTable的静态属性RouteCollection中,同时返回该route实例。路由注册完毕。

    MVC通过在IHttpModule的实现类UrlRoutingModule的Init方法中拦截HttpApplication的PostResolveRequestCache事件来处理请求。代码如下:

    public class UrlRoutingModule : IHttpModule
    {
        public RouteCollection RouteCollection
        {
        get
        {
            if (this._routeCollection == null)
            {
                this._routeCollection = RouteTable.Routes;
            }
            return this._routeCollection;
        }
        set
        {
            this._routeCollection = value;
        }
        }
        protected virtual void Init(HttpApplication application)
        {
        //省略
        application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
        }
    
        private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
        {
        HttpApplication httpApplication = (HttpApplication)sender;
        HttpContextBase context = new HttpContextWrapper(httpApplication.Context);
        this.PostResolveRequestCache(context);
        }
    
        public virtual void PostResolveRequestCache(HttpContextBase context)
        {
            RouteData routeData = this.RouteCollection.GetRouteData(context);
            //省略
            IRouteHandler routeHandler = routeData.RouteHandler;
            //省略
            RequestContext requestContext = new RequestContext(context, routeData);
            context.Request.RequestContext = requestContext;
            IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
            //省略
            if (!(httpHandler is UrlAuthFailureHandler))
            {
                context.RemapHandler(httpHandler);
                return;
            }
        //省略
        }
    }

     插一句,UrlRoutingModule中的RouteCollection默认来自对RouteTable的静态属性Routes的引用。

    拦截之后,通过RouteCollection的GetRouteData获得相应的路由数据RouteData的实例routeData。routeData有一个属性RouteHandler,在注册路由时,实例化Route时,我们实例化了一个MvcRouteHandler给构造函数,这里RouteHandler属性其实MvcRouteHandler的实例引用(如下代码片段中的Route)。

    然后我们routeHandler是的GetHttpHandler方法,获取到IHttpHandler(如下代码片段中的MvcRouteHandler 类)。

    //代码片段三
    public class Route : RouteBase
    {
        //省略
        public IRouteHandler RouteHandler
        {
            get;
            set;
        }
    
        public string Url
        {
            get
            {
                return this._url ?? string.Empty;
            }
            set
            {
                this._parsedRoute = RouteParser.Parse(value);
                this._url = value;
            }
        }
    
        public Route(string url, IRouteHandler routeHandler)
        {
            this.Url = url;
            this.RouteHandler = routeHandler;
        }
        
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
            RouteValueDictionary routeValueDictionary = this._parsedRoute.Match(virtualPath, this.Defaults);
            if (routeValueDictionary == null)
            {
                return null;
            }
            RouteData routeData = new RouteData(this, this.RouteHandler);
            if (!this.ProcessConstraints(httpContext, routeValueDictionary, RouteDirection.IncomingRequest))
            {
                return null;
            }
            foreach (KeyValuePair<string, object> current in routeValueDictionary)
            {
                routeData.Values.Add(current.Key, current.Value);
            }
            if (this.DataTokens != null)
            {
                foreach (KeyValuePair<string, object> current2 in this.DataTokens)
                {
                    routeData.DataTokens[current2.Key] = current2.Value;
                }
            }
            return routeData;
        }
        //省略
    }
    public class MvcRouteHandler : IRouteHandler
    { 
        //省略
        protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));
            return new MvcHandler(requestContext);
        }
        //省略
    }
  • 相关阅读:
    struts2学习笔记(二)
    struts2学习问题(一)
    struts2学习(一)
    给 ecplise 配置struts2配置环境
    Servlet的生命周期
    奇数位丢弃
    快速排序和归并排序(C语言)
    学习正则表达式及c#应用
    C#string与stringBuilder的区别
    c#之字符串函数
  • 原文地址:https://www.cnblogs.com/koeltp/p/7396096.html
Copyright © 2011-2022 走看看