欢迎访问我的个人博客:三秋邦

简说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);
    }
    //省略
}
posted @ 2017-08-19 12:02  追夢  阅读(265)  评论(0编辑  收藏  举报
欢迎访问我的个人博客:三秋邦