假设我只有这条路线:
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>
我们对Admin控制器上以Index操作方法为目标的URL的请求已由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
});
是无效的路由定义,因为只有路由的最后一段可以是可选的.否则,路由引擎无法消除您的路由歧义.
现在回到原来的问题,为什么对于那些路线,框架不会推断/索引部分.这是因为框架在评估您的路由模式时会看到:
{controller}/{action}/{id}/{name}
查看路线的{id}部分?当它分析这种模式时,它事先知道{action}部分后跟一个非可选的段(在你的情况下为{id}),你必须始终存在.而且因为它知道它,很明显它不能聪明并省略/索引部分,它甚至没有尝试.另一方面,您可以为最后一个段指定默认值,并在生成具有此值的路径时将省略该值.