在匹配不包含该参数的路由时,ActionLinks会恢复为查询字符串参数

时间:2013-03-21 20:25:37

标签: asp.net-mvc razor asp.net-mvc-4 asp.net-mvc-routing

我正在努力实现this目标,即将我的应用路线更改为:

hxxp://host/MyController/Widgets/3/AddWhatsit

此路线的视图将有助于用户向窗口小部件3添加Whatsit。

同样,我希望创建一个新的Widget的路由是:

hxxp://host/MyController/Widgets/Create

我已经创建了单独的路线来尝试和促进这一点。他们是:

           routes.MapRoute("DefaultAction",
                            "{controller}/{action}",
                            new {controller = "Home", action = "Index"});

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

我遇到的问题是当我浏览到Widgets的索引页面时(/ MyController / Widgets,匹配“DefaultAction”路由)任何引入了不属于该路由的新url参数的ActionLinks都会被转换进入查询字符串值。因此,例如,Widget 3的编辑链接将呈现为: Widget/Edit?id=3 instead of (what I would prefer): 窗口小部件/ 3 /编辑

我想我明白,通过不在路线的末尾放置我的(可选)id参数,我搞砸了。

我应该吸吮它并在路线尽头留下身份证明吗?

2 个答案:

答案 0 :(得分:2)

有可能实现这一目标。要获得类似/ Home / 1 / Index的锚链接,请设置以下路线:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Custom",
        url: "{controller}/{id}/{action}"
        );

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

然后,在视图中:

@Html.ActionLink("Here", "Index", "Home", new { id = 5 }, null)

你得到这样的链接:

<a href="/Home/5/Index">Here</a>

Quirk是限制自定义路线。我在这种情况下删除了默认值,它们没有意义。当然还有路线的顺序。

答案 1 :(得分:1)

我相信您需要更改路线的顺序。请记住,MVC会查看路线列表并选择第一个匹配路线。具有ID参数的第二个路由更具体,因此应该在路由表中排在第一位。

即使您在ActionLink中指定了ID参数,也指定了控制器和操作。因此,RoutingEngine正在选择第一条路由。

最后,删除ID属性的可选参数。由于您希望在拥有Id时选择该路由,因此您不希望它成为可选参数,您希望它与该路由匹配。

routes.MapRoute("Default","{controller}/{id}/{action}", 
   new {controller = "Home", action = "Index"});

routes.MapRoute("DefaultAction", "{controller}/{action}", 
  new {controller = "Home", action = "Index"});