ASP.NET MVC Route之WebForm路由与源码分析(二)
前言
在上一篇文中,我们介绍了WebForm路由与源码分析,并用一个实例的介绍了WebForm中如何使用路由和物理文件的逻辑隔离,那么Asp.Net是如何找到对应的物理文件的呢?下面我们通过源码进行分析。
源码分析
当我们输入要访问的URL地址时,请求会进入ASP.NET的管道处理程序,这是管道会遍历RouteCollection集合,找出符合当前请求的路由并返回。
下面是RouteCollection.cs中的GetRouteData方法代码:
public RouteData GetRouteData(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("httpContext"); } if (httpContext.Request == null) { throw new ArgumentException(SR.GetString("RouteTable_ContextMissingRequest"), "httpContext"); } if (base.Count == 0) { return null; } bool flag = false; bool flag2 = false; if (!this.RouteExistingFiles) { flag = this.IsRouteToExistingFile(httpContext); flag2 = true; if (flag) { return null; } } using (this.GetReadLock()) { foreach (RouteBase current in this) { RouteData routeData = current.GetRouteData(httpContext); if (routeData != null) { RouteData result; if (!current.RouteExistingFiles) //是否启用物理文件,默认为True { if (!flag2) { flag = this.IsRouteToExistingFile(httpContext); flag2 = true; } if (flag) { result = null; return result; } } result = routeData; return result; } } } return null; }
上述红色代码是在遍历RouteCollection中的每一个路由且把httpcontext当做参数,调用Route类的GetRouteData()方法,从而获取匹配的Route信息,如果RouteCollection集合中有符合当前的URL的Route时,就立即返回,否则为NULL。 下面我们看看Route的GetRouteData()源码
public override RouteData GetRouteData(HttpContextBase httpContext) { string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2) + httpContext.Request.PathInfo; RouteValueDictionary routeValueDictionary = this._parsedRoute.Match(virtualPath, this.Defaults); //结合默认值,匹配url 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; }
Route对象的GetRouteData方法会匹配URL模式和检查约束条件,如何不符合会返回null。如果匹配,则new一个RouteData