我想知道下面代码中HttpContext.Request.AppRelativeCurrentExecutionFilePath的功能是什么.请解释路由系统如何匹配请求的URL:
public override RouteData GetRouteData(HttpContextBase httpContext) { RouteData result = null; string requestedURL = string.Empty; for (int i = 0; i < urls.Length; i++) { if(httpContext.Request.AppRelativeCurrentExecutionFilePath.Contains(urls[i])) { requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath; break; } } if (!string.IsNullOrEmpty(requestedURL)) { result = new RouteData(this,new MvcRouteHandler()); result.Values.Add("controller","CustomRoute"); result.Values.Add("action","DirectCustomUrls"); result.Values.Add("customUrl",requestedURL); } return result; }
解决方法
路由系统
works like a switch-case statement.匹配wins的第一个路由以及之后注册的所有路由将被忽略.
因此,每个路由都没有一个,而是三个单独的责任(无论路由是传入的HTTP请求还是传出的URL生成):
>匹配请求.
>如果请求匹配,则提供一组路由值(或URL生成时的虚拟路径).
>如果请求不匹配,则返回null.
您发布的代码完成了所有这三项任务.
匹配请求
string requestedURL = string.Empty; for (int i = 0; i < urls.Length; i++) { if(httpContext.Request.AppRelativeCurrentExecutionFilePath.Contains(urls[i])) { requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath; break; } } if (!string.IsNullOrEmpty(requestedURL)) {
上面的代码通过检查URL值数组来匹配请求.基本上,它说的是“如果数组包含当前请求的URL,那么它就是匹配”.
实际检查它是否匹配是行if(!string.IsNullOrEmpty(requestedURL)),如果URL包含默认值String.Empty以外的值,则允许条件通过.
提供一组路线值
result = new RouteData(this,new MvcRouteHandler()); result.Values.Add("controller","CustomRoute"); result.Values.Add("action","DirectCustomUrls"); result.Values.Add("customUrl",requestedURL);
上面的代码创建了一个新的RouteData对象,该对象由标准的MvcRouteHandler支持.
然后它填充结果的路由值.对于MVC,需要控制器和操作,并且值可能包含其他内容,如主键,当前文化,当前用户等.
返回null
RouteData result = null; // <snip> if (!string.IsNullOrEmpty(requestedURL)) { // <snip> } return result;
上面的代码设置了一个模式,以确保当路由与请求不匹配时,返回的结果为null.
这一步非常重要.如果在不匹配的情况下不返回null,则路由引擎将不检查在当前路由之后注册的任何路由.
考虑这个路由配置:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new CustomRoute()); routes.MapRoute( name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home",action = "Index",id = UrlParameter.Optional } ); } }
如果在传入请求与路由不匹配的情况下CustomRoute未能返回null,则路由框架将永远不会检查默认路由.这使得CustomRoute非常不灵活,因为它无法在配置中的任何其他路由之前注册.