Search code examples
c#asp.netasp.net-mvcroutesurlhelper

Is UrlHelper.Action Equivalent to UrlHelper.RouteUrl?


I want to replace all instances of UrlHelper.Action with UrlHelper.RouteUrl in my code because of the performance benefits. According to the documentation, both methods will generate a fully qualified URL, I want to confirm that they will return the exact same URL.


Example:

Assuming that the routes in RouteConfig have unique controller, action combinations:

Given the following route in RouteConfig:

routes.MapRoute(
    "RouteName",
    "Url",
    new { controller = "Controller", action = "Action" }
);

Is it safe to assume that

urlHelper.Action("Action", "Controller", routeValueDictionary);

is exactly equivalent to

urlHelper.RouteUrl("RouteName", routeValueDictionary);

Solution

  • Once there are no routes mapped above your displayed mapping that can match the route generated from

    urlHelper.Action("Action", "Controller", routeValueDictionary);
    

    then you would be safe in your assumption in using the route name.

    if for example you have two routes defined like this...

    routes.MapRoute(
        "AnotherRouteName",
        "{controller}/blah/{action}",
        new { controller = "Controller", action = "Action" }
    );
    
    routes.MapRoute(
        "RouteName",
        "Url",
        new { controller = "Controller", action = "Action" }
    );
    

    ...then the first route would be matched by..

    urlHelper.Action("Action", "Controller", routeValueDictionary);
    

    UPDATE:

    if you look at the source for UrlHelper

    You will notice that internally they are calling the same overloads of the same methods with relevant arguments.

    public virtual string Action(string actionName, string controllerName, object routeValues)
    {
        return GenerateUrl(null /* routeName */, actionName, controllerName, TypeHelper.ObjectToDictionary(routeValues));
    }
    
    public virtual string Action(string actionName, string controllerName, RouteValueDictionary routeValues)
    {
        return GenerateUrl(null /* routeName */, actionName, controllerName, routeValues);
    }
    
    //...other code removed for brevity
    
    public virtual string RouteUrl(string routeName, object routeValues, string protocol)
    {
        return GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, null /* hostName */, null /* fragment */, TypeHelper.ObjectToDictionary(routeValues), RouteCollection, RequestContext, false /* includeImplicitMvcValues */);
    }
    

    Way too much code to post here. take a look at the class source to get a better understanding of what is happening under the hood.

    Can't provide any more detail than that. I've gone all the way back to the source code.