在生成传出 URL 时针对其他控制器中的相同操作方法
Targeting same action method in other controllers while generating an outgoing URL
假设我只有这条路线:
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
我们可以看到我们的启动页会是Home/Index
.
假设我在视图中使用此代码创建了一个锚元素:
@Html.ActionLink("This targets another controller","Index", "Admin")
当我渲染视图时,您将看到生成以下 HTML:
<a href="/Admin">This targets another controller</a>
我们对 URL 的请求以 Admin
控制器上的 Index
操作方法为目标,已被 ActionLink
方法表示为 /Admin
。路由系统非常聪明,它知道应用程序中定义的路由默认使用 Index
操作方法,允许它省略不需要的段。
问题是:
如果我将路线更改为:
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{name}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
name = UrlParameter.Optional
});
或 如:
routes.MapRoute("Default", "{controller}/{action}/{id}/{*catchall}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
然后,将生成以下HTML:
<a href="/Admin/Index">This targets another controller</a>
你能解释一下为什么吗?
两者:
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{name}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
name = UrlParameter.Optional
});
和:
routes.MapRoute("Default", "{controller}/{action}/{id}/{*catchall}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
是无效的路由定义,因为只有路由的最后一段可以是可选的。否则路由引擎无法消除您的路由歧义。
现在回到您最初的问题,即为什么框架不为这些路由推断 /Index
部分。这是因为框架在评估您的路由模式时会看到:
{controller}/{action}/{id}/{name}
看到您路线的 {id}
部分了吗?当它分析这个模式时,它预先知道 {action}
部分后面跟着一个 非可选的 段({id}
在你的情况下)你必须 总是在场。并且因为它知道它,所以很明显它不能很聪明并省略 /Index
部分而且它甚至没有尝试这样做。另一方面,您可以为 last 段指定一个默认值,并且在使用该值生成路由时将忽略它。
假设我只有这条路线:
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
我们可以看到我们的启动页会是Home/Index
.
假设我在视图中使用此代码创建了一个锚元素:
@Html.ActionLink("This targets another controller","Index", "Admin")
当我渲染视图时,您将看到生成以下 HTML:
<a href="/Admin">This targets another controller</a>
我们对 URL 的请求以 Admin
控制器上的 Index
操作方法为目标,已被 ActionLink
方法表示为 /Admin
。路由系统非常聪明,它知道应用程序中定义的路由默认使用 Index
操作方法,允许它省略不需要的段。
问题是:
如果我将路线更改为:
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{name}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
name = UrlParameter.Optional
});
或 如:
routes.MapRoute("Default", "{controller}/{action}/{id}/{*catchall}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
然后,将生成以下HTML:
<a href="/Admin/Index">This targets another controller</a>
你能解释一下为什么吗?
两者:
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{name}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
name = UrlParameter.Optional
});
和:
routes.MapRoute("Default", "{controller}/{action}/{id}/{*catchall}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
});
是无效的路由定义,因为只有路由的最后一段可以是可选的。否则路由引擎无法消除您的路由歧义。
现在回到您最初的问题,即为什么框架不为这些路由推断 /Index
部分。这是因为框架在评估您的路由模式时会看到:
{controller}/{action}/{id}/{name}
看到您路线的 {id}
部分了吗?当它分析这个模式时,它预先知道 {action}
部分后面跟着一个 非可选的 段({id}
在你的情况下)你必须 总是在场。并且因为它知道它,所以很明显它不能很聪明并省略 /Index
部分而且它甚至没有尝试这样做。另一方面,您可以为 last 段指定一个默认值,并且在使用该值生成路由时将忽略它。