MVC2为什么只有我的第一条路线被认可?

时间:2012-02-13 16:51:41

标签: asp.net-mvc-2 routes

所以现在我有两条路线:

routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

           routes.MapRoute(
               "Legos",
               "{controller}/{action}/{page}",
               new { controller = "Legos", action = "Lego", page = UrlParameter.Optional });

如果我转到www.website.com,我将能够很好地看到我的主页,但我的Legos路线无效。同样,如果我把我的Legos路线放在最前面,我可以去www.website.com/Legos/Lego/1就好了,但是去www.website.com发错了(下面),我需要手动去到www.website.com/Home/Index查看我的主页。

错误:

The parameters dictionary contains a null entry for parameter 'page' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Errors(Int32, System.String)' in 'stuff.Controllers.Legos'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters

为什么会这样?

1 个答案:

答案 0 :(得分:1)

原因是这两个路由具有相同数量的参数且没有约束,因此路由处理程序无法区分它们的入站请求 - 它将与第一个匹配(即添加到路由表中的任何一个)第一)。

如果您正确地区分了您的路线,那么它将起作用。例如,您可以尝试从“默认”路由中删除“id”可选参数,并强制要求“Legos”路由的“页面”部分(因为它似乎是端点工作所必需的,这是最好的无论如何都要练习):

routes.MapRoute(
    "Legos",
    "{controller}/{action}/{page}",
    new { controller = "Legos", action = "Lego", page = 1 });

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}", // URL with parameters
    new { controller = "Home", action = "Index" } // Parameter defaults
);

这意味着具有两个参数(即Home / Index)的url与“Legos”路由不匹配,因为它缺少所需的“page”参数 - 然后它将测试“Default”路由,这将成功,因为“Home / Index”匹配它所期望的“{anything} / {anything}”格式。

您的另一个选择是为其中一条路线添加路线约束 - 例如,您可以使“页面”仅接受数字,因此如果传入的请求看起来像{anything} / {anything} / {numeric}那么将匹配“Legos”路线,但如果它是非数字的,它将不匹配约束,而是会命中默认路线:

routes.MapRoute(
"Legos",
url: "{controller}/{action}/{page}",
defaults: new { controller = "Legos", action = "Lego" },
constraints: new { page = @"([0-9]+)" } ); // constrain to "one or more numbers" - constraints are simply regular expressions

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

当然,这个特定解决方案的“问题”是,如果你有一个数字id(让我们面对它,大多数是你想要用于“默认”路线),它最终会被“乐高积木”路线......