创建自定义RouteBase类

时间:2016-04-21 07:15:47

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

我想知道下面代码中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; 
}

1 个答案:

答案 0 :(得分:1)

路由系统works like a switch-case statement。第一个匹配wins的路由,以及之后注册的所有路由都将被忽略。

因此,每个路由都没有一个,而是三个单独的责任(无论路由是传入的HTTP请求还是传出的URL生成):

  1. 匹配请求。
  2. 如果请求匹配,请提供一组路由值(或URL生成时的虚拟路径)。
  3. 如果请求不匹配,请返回null
  4. 您发布的代码完成了所有这三项任务。

    匹配请求

    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)),如果网址包含默认值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,controlleraction是必需的,值可能包含其他内容,如主键,当前文化,当前用户等。

    返回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,则路由框架永远不会检查Default路由。这使得CustomRoute非常不灵活,因为它无法在配置中的任何其他路由之前注册。