asp.net mvc源码分析-Route的GetRouteData

本文深入探讨了ASP.NET MVC中Route的GetRouteData方法,通过分析MapRoute设置、请求路径处理、约束检查和匹配过程,揭示了路由数据如何与HTTP请求结合,帮助读者理解路由在MVC框架中的工作原理。
摘要由CSDN通过智能技术生成

我知道Route这里东西应该算路由,这里把它放到mvc里面有些不怎么合适,但是我想大家多数遇到路由都是在mvc的时候吧.首先我们还是来看看GetRouteData方法吧

public override RouteData GetRouteData(HttpContextBase httpContext)
{
    string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo;
    RouteValueDictionary values = this._parsedRoute.Match(virtualPath, this.Defaults);
    if (values == null)
    {
        return null;
    }
    RouteData data = new RouteData(this, this.RouteHandler);
    if (!this.ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest))
    {
        return null;
    }
    foreach (KeyValuePair<string, object> pair in values)
    {
        data.Values.Add(pair.Key, pair.Value);
    }
    if (this.DataTokens != null)
    {
        foreach (KeyValuePair<string, object> pair2 in this.DataTokens)
        {
            data.DataTokens[pair2.Key] = pair2.Value;
        }
    }
    return data;
}
我还是沿用以前的思路,已一个demo来便说明吧,现在假设我的路由信息是:

   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
            routes.MapRoute(
                "Default", // 路由名称
                "{controller}/{action}/{id}", // 带有参数的 URL
                new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // 参数默认值
                new { controller="([A-Za-z])*" },
                new string[] { "MvcApp.Controllers" }
            );

   请求路径: http://localhost:7503/Home/index
我们知道httpContext.Request.AppRelativeCurrentExecutionFilePath的返回值都是以~/打头的,这里httpContext.Request.PathInfo为空,多数情况下该属性也是空的,所以这里的virtualPath=Home/index

有关MapRoute的代码可以参照

  public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) {
            if (routes == null) {
                throw new ArgumentNullException("routes");
            }
            if (url == null) {
                throw new ArgumentNullException("url");
            }

            Route route = new Route(url, new MvcRouteHandler()) {
                Defaults = new RouteValueDictionary(defaults),
                Constraints = new RouteValueDictionary(constraints),
                DataTokens = new RouteValueDictionary()
            };

            if ((namespaces != null) && (namespaces.Length > 0)) {
                route.DataTokens["Namespaces"] = namespaces;
            }

            routes.Add(name, route);

            return route;
        }

首先调用_parsedRoute.Match(virtualPath, this.Defaults)获取一个RouteValueDictionary ,至于这个方法的具体实现放到后面来说,然后实例化一个RouteData ,并且把先前的RouteValueDictionary的值添加到先前实例化的  RouteData中,如果DataTokens有元素的话也加入到RouteData的DataTokens中来。不过这个过程有个约束的处理

 if (!this.ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest))
    {
        return null;
    }

其中RouteDirection的定义如下:
    public enum RouteDirection
{
    IncomingRequest,
    UrlGeneration
}
约束检查失败而返回null,现在我们来看看ProcessConstraints方法:

private bool ProcessConstraints(HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection)
{
    if (this.Constraints != null)
    {
        foreach (KeyValuePair<string, object> pair in this.Constraints)
        {
            if (!this.ProcessConstraint(httpContext, pair.Value, pair.Key, values, routeDirection))
            {
                return false;
            }
        }
    }
    return true;
}

如果Constraints有元素,依次检查每个成员,检查方法主要是调用ProcessConstraint方法,

protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
    object obj2;
    IRouteConstraint constraint2 = constraint as IRouteConstraint;
    if (constraint2 != null)
    {
        return constraint2.Match(httpContext, this, parameterName, values, routeDirection);
    }
    string str = constraint 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值