|
用asp.net mvc以来,UrlRouting的处理就是一个非常关键的问题,由于使用的不小心,经常导致我们无法得到预期的结果,这的确是个很麻烦的问题,于是很多朋友推测是MVC框架的bug,到底事实如何呢?今天我便尽力探索系统中UrlRouting到底是如何工作的,希望能找出问题的关键. 总所周知,Asp.Net MVC框架一般使用Global.asax在程序第一次启动的时候初始化RouteCollection,在Preview3中,我们一般使用RouteCollection. MapRoute方法来添加新的规则.然后,系统理论上会非常听话执行我们给出的规则,然后我们直接或者间接在页面中使用UrlHelper提供的方法处理Url,UrlHelper使用路由而非路径的方式定义url,能给我们更大的方便,但是问题来了,很多朋友发现UrlHelper并不是那么听话的,可以说有时候会给出一个莫名其妙的地址.为了解开这个问题,我们得先看看系统到底怎么来处理这些规则的. 首先我们把这个MapRoute方法找出来,查询源代码: Route route = new Route(url, new MvcRouteHandler()) { if (String.IsNullOrEmpty(name)) {
这是一个扩展方法,我们看到这实际上是简化了PreView2中添加路由的方式.这儿仍然和以前一样使用routes.Add方法来添加路由,由于System.Web.Routing手上没有源码,只好使用反编译该程序集来研究,我们再看RouteCollection的关键定义: public class RouteCollection : Collection<RouteBase>
这表明实际上RouteCollection维护了两个容器,一个是Collection,一个是Dictionary public void Add(string name, RouteBase item) 如果未提供name参数,则直接使用Collection提供的Add方法添加Route,这时并没有向_ namedMap添加route,只有提供了name,且提供的name满足!IsNullOrEmpty参数才会向_namedMap添加规则.ok,这下明白了RouteCollection是如何存储路由规则了,我们继续看UrlHelper部分和Url有关的主要提供了Action, Content和RouteUrl3个方法,而RouteUrl和Action方法则都是调用了UrlHelper.GenerateUrl方法,至于其他和Url有关的部分,如HtmlHelper也都是直接或者间接调用UrlHelper.GenerateUrl方法.我们一个个查看. 首先看Action,该方法会给出一个连接到所提供的action的url,有好几个重载,但是总结起来都是调用return GenerateUrl(null /* routeName */, actionName,xxx,xxx)的模式,也就是说前面所有Action间接调用GenerateUrl时候前两个参数固定,一个是null,一个是actionName,而在RouteUrl中则不同,会根据不同的重载模式来,既有需要routeName的,也有不需要routeName的.现在关键就是GenerateUrl方法了,该方法代码如下:
internal static string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary valuesDictionary, RouteCollection routeCollection, ViewContext viewContext) { if (vpd != null) { 关键是第二个,分析下这个方法,它要求必须唯一提供action,且不能重复提供controller,然后,对于路径的查找,如果提供了routeName,则系统会使用GetVirtualPath(viewContext, routeName, valuesDictionary);否则使用routeCollection.GetVirtualPath(viewContext, valuesDictionary); (责任编辑:admin) |





骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价