这是我今天早上使用ASP.NET MVC的URL路由时遇到的一个问题的精简示例 .
相当简单,我想要调用路径的Action,无论是否提供了最后的参数 .
这条路线工作正常,匹配 /apple/ 和 /apple/test/
routes.MapRoute(
"Working Route",
"apple/{parameter}",
new {
controller = "Apple",
action = "Action",
parameter = UrlParameter.Optional
},
new { parameter = @"([a-z0-9\.-]+)" }
);
但是,第二条路线仅匹配 /banana/test/ 等 . 当我尝试 /banana/ 时,路由器只是正好通过它并返回catch-all 404错误 .
routes.MapRoute(
"Non-Working Route",
"banana/{parameter}",
new {
controller = "Banana",
action = "Action",
parameter = UrlParameter.Optional
},
new { parameter = @"([a-z0-9]+)" }
);
唯一的区别是参数的正则表达式验证,但由于它是一个非常简单的正则表达式匹配,它们应该完全适用于像 /banana/ 这样的URL,但第二条路线无法识别它 .
我只是通过改变路线#2上的正则表达式以匹配路线#1上的正则表达式来解决我的问题,并接受' . '和' - '字符,我只是想知道是否有人知道为什么这似乎正在发生 .
编辑:
以下是我用于示例的控制器和操作 . 没什么好看的 .
public class AppleController : Controller
{
public ActionResult Action(string parameter)
{
if (parameter == null)
{
parameter = "No parameter specified.";
}
ViewData["parameter"] = parameter;
return View();
}
}
public class BananaController : Controller
{
public ActionResult Action(string parameter)
{
if (parameter == null)
{
parameter = "No parameter specified.";
}
ViewData["parameter"] = parameter;
return View();
}
}
所以我的问题是 /apple/ 会显示"No parameter specified.",而 /banana/ 会给我一个不受欢迎的404 .
到目前为止..
在Route声明中使用 parameter = URLParameter.Optional :Route#1完美运行,没有参数,Route#2不匹配 .
在Route声明中使用 parameter = "" :当参数不在URL时,Route#1和Route#2都不匹配 .
在Action方法签名中声明 parameter = "" :由于.NET版本不可能 .
删除所有其他路由无效 .
2 回答
如果令牌是可选的,那么您使用的任何正则表达式约束也必须反映,例如
(foo)?
.我能够在.NET 4上使用ASP.NET MVC 2重现这个问题 . 然后我升级到ASP.NET MVC 3,一切都按预期工作 . 我上面提到的解决方案不适用于ASP.NET MVC 2,但它适用于ASP.NET MVC 3,因此我只能假设这是v2上的一个错误,现在已在v3中修复 .
您可以引用v2,并在web.config上使用它来测试v3:
第二次编辑
匹配〜/水果/和〜水果/苹果
匹配〜/ banana /和〜/ banana / yellow
第一次编辑
尝试在操作签名上将参数实际设置为可选,例如:
string parameter = ""
我没有得到那种行为 . 当你描述它们时,这两条路线都适用于我(如果我在路线上添加“ - ”,则第二条路线会抛出404,但这是预期的) . 你的行动方法签名是什么样的?
我将我的路线(和控制器/视图)设置为:
我的Index()动作如下所示: