UrlHelper.Action是否等同于UrlHelper.RouteUrl?

时间:2016-06-09 16:00:16

标签: c# asp.net asp.net-mvc routes urlhelper

由于UrlHelper.Action,我想在代码中用UrlHelper.RouteUrl替换performance benefits的所有实例。根据文档,这两种方法都会生成一个完全限定的URL,我想确认它们将返回完全相同的URL。

示例:

假设RouteConfig中的路由具有唯一的controlleraction组合:

RouteConfig中给出以下路线:

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

假设

是否安全
urlHelper.Action("Action", "Controller", routeValueDictionary);

完全等同于

urlHelper.RouteUrl("RouteName", routeValueDictionary);

2 个答案:

答案 0 :(得分:1)

在显示的映射上方没有映射的路由可以匹配从

生成的路由
urlHelper.Action("Action", "Controller", routeValueDictionary);

那么你在使用路线名称的假设是安全的。

例如,如果您有两条像这样定义的路线...

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

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

...然后第一条路线将匹配..

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

更新:

如果您查看UrlHelper

的来源

您会注意到,在内部,他们使用相关参数调用相同方法的相同重载。

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

这里发布的代码太多了。看看课程来源,以便更好地了解幕后发生的事情。

无法提供更多细节。我已经一直回到源代码。

答案 1 :(得分:0)

不,不完全是。

urlHelper.RouteUrl只会为路线添加额外的过滤器。您仍然必须提供匹配的参数(包括controlleraction),否则它将返回null而不是您期望的网址。

urlHelper.RouteUrl("RouteName", 
    new { controller = "Controller", action = "Action"[, other route values... ]);

主要区别在于此过滤器仅使路由框架按顺序检查一条路由而不是所有路由。这使得在生成URL时无法匹配错误的路由,但传入的请求仍然可能通过以错误的顺序将它们放入路由表中来匹配错误的路由 - 这意味着您可能会从路由表中生成不能生成的URL实际上可以在应用程序中访问。

  

除非您的路线表中有数千条路线,否则您不太可能看到任何明显的性能差异。

这是否有任何实际好处值得怀疑。事实上,ActionRouteUrl最终都会在UrlHelper中调用完全相同的方法来生成网址。无论您使用Action还是RouteUrl生成网址,您仍应make unit tests确保传入路由与您预期的路线匹配,并返回正确的路由值集。

RouteUrl确实有Action没有的好处 - 您可以传递null作为路由名称(或调用没有路由名称的重载),这样您就可以通过它是一组现成的路由值,无需为controlleraction显式设置单独的参数。这使RouteUrl的行为与Action完全相同,但可以更轻松地与动态处理路径值的代码集成。

urlHelper.RouteUrl(routeValueDictionary);