0

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


例子:

假设中的路线RouteConfig具有独特的controller,action组合:

鉴于以下路线RouteConfig

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

可以安全地假设

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

完全等同于

urlHelper.RouteUrl("RouteName", routeValueDictionary);
4

2 回答 2

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

太多代码在这里发布。查看类源以更好地了解幕后发生的事情。

不能提供比这更详细的了。我一直回到源代码。

于 2016-06-09T16:53:57.257 回答
0

不,不完全是。

urlHelper.RouteUrl只为路由添加一个额外的过滤器。您仍然必须提供匹配的参数(包括controllerand action),否则它将返回null而不是您期望的 URL。

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

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

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

这是否有任何真正的好处值得怀疑。事实上,两者Action最终RouteUrl都调用了完全相同的方法UrlHelper来生成 URL。无论您是使用Action还是RouteUrl生成 URL,您仍应进行单元测试以确保传入路由与您预期的路由匹配并返回正确的路由值集。

RouteUrl确实有一个没有的好处Action- 您可以null作为路由名称传递(或调用没有路由名称的重载),这允许您将一组现成的路由值传递给它,而无需显式设置单独的参数controlleraction. 这使得RouteUrl行为与 完全一样Action,但更容易与动态操作路由值的代码集成。

urlHelper.RouteUrl(routeValueDictionary);
于 2016-06-09T16:54:10.193 回答