这是我今天早上使用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",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:
路线#1工作正常,没有参数,路线#2不匹配.
在Route声明中使用parameter =“”:
路线#1和路线都是当参数不在URL时,路径#2无法匹配.
在Action方法签名中声明参数=“”:
由于.NET版本不可能.
删除所有其他路由无效.
解决方法
如果令牌是可选的,那么您使用的任何正则表达式约束也必须反映,例如(富)?
我能够在.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>