这是我今天早上使用ASP.NET MVC的URL路由时遇到的问题的简要示例。
相当简单,我想要调用路径的动作,无论是否提供了最后的参数。
此路线正常,与 / 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 / 时,路由器只是直接通过它并返回全部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 / 会显示“没有指定参数。”,而 / banana / 会给我一个不需要的404。
<小时/> 到目前为止..
在路线声明中使用 parameter = URLParameter.Optional : 路线#1运行良好,没有参数,路线#2不匹配。
在路线声明中使用参数=“”: 路线#1和路线都是当参数不在URL时,路径#2无法匹配。
在Action方法签名中声明 parameter =“”: 由于.NET版本不可能。
删除所有其他路线无效。
答案 0 :(得分:4)
如果令牌是可选的,那么您使用的任何正则表达式约束也必须反映,例如(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:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
答案 1 :(得分:0)
第二次编辑
匹配〜/ fruit /和~fruit / apple
routes.MapRoute(
"Working Route",
"Fruit/{fruit}",
new
{
controller = "Fruit",
action = "Index",
fruit = ""
},
new { fruit = @"([a-z0-9\.-]+)" }
);
public ActionResult Index(string fruit)
{
ViewData["fruit"] = !String.IsNullOrEmpty(fruit) ? fruit : "None specified.";
return View();
}
匹配〜/ banana /和〜/ banana / yellow
routes.MapRoute(
"Non-Working Route",
"Banana/{color}",
new
{
controller = "Banana",
action = "Index",
color = ""
},
new { color = @"([a-z0-9]+)" }
);
public ActionResult Index(string color)
{
ViewData["Color"] = color;
return View();
}
第一次编辑
尝试在动作签名上实际将参数设置为可选,例如:string parameter = ""
我没有得到那种行为。当你描述它们时,这两条路线都适用于我(如果我在路线上添加“ - ”,则第二条路线会抛出404,但这是预期的)。你的行动方法签名是什么样的?
我将路线(和控制器/视图)设置为:
routes.MapRoute(
"Working Route",
"Fruit/{fruit}",
new
{
controller = "Fruit",
action = "Index",
fruit = UrlParameter.Optional
},
new { fruit = @"([a-z0-9]+)" }
);
我的Index()动作如下:
public ActionResult Index(string fruit = "")
{
ViewData["fruit"] = fruit;
return View();
}