Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
933 views
in Technique[技术] by (71.8m points)

asp.net mvc - Creating Custom RouteBase class

I want to know what is the function of HttpContext.Request.AppRelativeCurrentExecutionFilePath in below code. Please, explain how the routing system matches the requested 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; 
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The routing system works like a switch-case statement. The first route that matches wins, and all routes that are registered afterward are ignored.

Therefore, each route has not one, but three separate responsibilites (whether the route is an incoming HTTP request or an outgoing URL generation):

  1. To match the request.
  2. If the request matches, provide a set of route values (or a virtual path in the case of URL generation).
  3. If the request doesn't match, return null.

The code you posted does all three of these tasks.

Matching the Request

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)) 
{

The above code matches the request by checking it against an array of URL values. Basically, all it says is "if the array contains the URL of the current request, it is a match".

The actual check whether it matches is the line if (!string.IsNullOrEmpty(requestedURL)), which allows the condition to pass if the URL contains a value other than the default of String.Empty.

Providing a Set of Route Values

    result = new RouteData(this, new MvcRouteHandler()); 
    result.Values.Add("controller", "CustomRoute"); 
    result.Values.Add("action", "DirectCustomUrls"); 
    result.Values.Add("customUrl", requestedURL);

The above code creates a new RouteData object which is backed by the standard MvcRouteHandler.

Then it populates the route values of the result. For MVC, controller and action are required, and the values may contain other things like primary keys, current culture, current user, etc.

Returning null

RouteData result = null; 

// <snip>

if (!string.IsNullOrEmpty(requestedURL)) 
{
    // <snip>
}

return result;

The above code sets up a pattern to ensure that when the route does not match the request, the result returned is null.

This step is extremely important. If you don't return null in the case of a non-match, the routing engine will not check any routes registered after the current one.

Consider this route configuration:

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 }
        );
    }
}

If CustomRoute fails to return null in the case the incoming request does not match the route, the routing framework will never check the Default route. This makes CustomRoute extremely inflexible because it cannot be registered before any other route in the configuration.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...