为什么这个MVC路由不起作用?

时间:2009-03-24 12:29:36

标签: asp.net-mvc routes

这是我的global.asax文件中的两个路由。我正在尝试进入第二条路线,我收到了一个默认的404资源未找到错误。

当我删除第一条路线(在此示例中列出)时,它可以正常工作。

我该如何解决这个问题?

global.asax代码片段

// GET: /user/PureKrome/Alert/69
routes.MapRoute(
    "User-Alert-Details",
    "user/{displayName}/alert/{alertId}",
    new { controller = "Account", action = "AlertDetails", alertId = 0 });

// GET: /user/PureKrome/Alert/create
routes.MapRoute(
    "User-Alert-Create",
    "user/{displayName}/alert/create",
    new { controller = "Account", action = "AlertCreate" });

4 个答案:

答案 0 :(得分:20)

您的第一条路线是“贪婪”路线,并乐意接受“创建”作为最后一个参数中的alertId。您似乎打算将alertId参数设置为仅数字,因此您应该添加一个约束来告诉路由系统该最后一个参数必须是数字。

请参阅此tutorial

例如:

// GET: /user/PureKrome/Alert/69
routes.MapRoute(
    "User-Alert-Details",
    "user/{displayName}/alert/{alertId}",
    new { controller = "Account", action = "AlertDetails", alertId = 0 },
    new { alertId = @"\d+" });

// GET: /user/PureKrome/Alert/create
routes.MapRoute(
    "User-Alert-Create",
    "user/{displayName}/alert/create",
    new { controller = "Account", action = "AlertCreate" });

注意,您也可以反转路线的顺序,但即使您这样做,如果您希望alertId始终为数字,您仍应该包含正确性约束。

答案 1 :(得分:1)

您希望以相反的方式定义路线,以便create上的完全匹配位于alertId的无约束匹配之前。那,或者您可以按照Twisty Maze的说明向alertId添加约束。

这是因为路由通过尝试匹配从上到下的路由来工作。 /user/PureKrome/Alert/create路线上的User-Alert-Details匹配,因为它认为createalertId的值。如果第4段明确User-Alert-Create,那么通过切换它们只会匹配create路线,如果不明确,则会落到User-Alert-Details

为清楚起见,他们应该以这种方式工作:

// GET: /user/PureKrome/Alert/create
routes.MapRoute(
    "User-Alert-Create",
    "user/{displayName}/alert/create",
    new { controller = "Account", action = "AlertCreate" });

// GET: /user/PureKrome/Alert/69
routes.MapRoute(
    "User-Alert-Details",
    "user/{displayName}/alert/{alertId}",
    new { controller = "Account", action = "AlertDetails", alertId = 0 });  

答案 2 :(得分:1)

如果您还有其他问题,请在http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx

尝试Phil Haack的网址调试器

答案 3 :(得分:0)

问题是您已在第一个映射中为控制器和操作指定了默认值。

现在任何传入请求都由第一个路由处理,如果缺少控制器名称,则将其替换为默认值,如果缺少操作名称,也会替换为默认值。

所以当你说http://localhost/SomeRoute时 第一个映射器开始运行并将字符串“SomeRoute”视为控制器名称,然后它找不到该操作,因此它使用您指定的默认操作,在您的示例中为“AlertCreate”。 所以现在映射器试图在“SomeRoute”控制器中找到一个名为AlertCreate的Action。

底线是第二个映射没有开始执行,因为第一个映射正在处理所有路由请求。 (因为您指定了默认值)