在生成传出URL时,在其他控制器中定位相同的操作方法

时间:2015-02-05 17:39:12

标签: c# asp.net-mvc asp.net-mvc-routing

我们说我只有这条路线:

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> 

我们针对Index控制器上Admin操作方法的网址请求已被/Admin方法表示为ActionLink。路由系统非常聪明,它知道应用程序中定义的路由默认使用Index操作方法,允许它省略不需要的段。

问题是:

如果我将路线更改为:

routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{name}",
        new
        {
            controller = "Home",
            action = "Index",
            id = UrlParameter.Optional,
            name = UrlParameter.Optional
        });

as:

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>

你能解释一下为什么吗?

1 个答案:

答案 0 :(得分:2)

这两种:

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部分,它甚至没有尝试。另一方面,您可以为最后段指定默认值,并在生成具有此值的路径时将省略该值。