为什么使用此正则表达式时 ASP.NET-MVC 路由的 UrlParameter.Optional 被忽略?
这是我今天早上遇到的 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/ 时,路由器直接越过它并返回包罗万象的 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 。
So far..
在路由声明中使用 parameter = URLParameter.Optional: 路线#1 工作正常,路线#2 在没有参数的情况下不匹配。
在路由声明中使用 parameter = "": 路线 #1 和路线 #1当 URL 中省略该参数时,路由 #2 无法匹配。
在 Action 方法签名中声明 parameter = "": 由于 .NET 版本的原因,不可能。
删除所有其他路由没有任何效果。
This is a stripped down example of a problem I was having this morning with ASP.NET MVC's URL routing.
Fairly simple, I wanted a route's Action to be called, whether or not the parameter on the end was supplied.
This route works fine, matching both /apple/ and /apple/test/
routes.MapRoute( "Working Route", "apple/{parameter}", new { controller = "Apple", action = "Action", parameter = UrlParameter.Optional }, new { parameter = @"([a-z0-9\.-]+)" } );
However, this second route will only match /banana/test/ and the like. When I try /banana/, the router just passes right over it and returns the catch-all 404 error.
routes.MapRoute( "Non-Working Route", "banana/{parameter}", new { controller = "Banana", action = "Action", parameter = UrlParameter.Optional }, new { parameter = @"([a-z0-9]+)" } );
The only difference is the Regex validation of the parameter, but as it's quite a simple Regex match, they should both work perfectly fine for a URL like /banana/, yet the second route just fails to recognise it.
I side-stepped my problem by just changing the Regex on route #2 to match that on route #1, and accept the '.' and '-' characters, I just wondered if anyone knows why this seems to be happening.
EDIT:
Here are the Controllers and Actions that I'm using for my example. Nothing fancy here.
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(); } }
So my problem is that /apple/ would display "No parameter specified.", while /banana/ gives me an undesired 404 instead.
So far..
Using parameter = URLParameter.Optional in the Route declaration:
Route #1 works perfectly, Route #2 doesn't match without the parameter.
Using parameter = "" in the Route declaration:
Both Route #1 & Route #2 fail to match when the parameter is left off the URL.
Declaring parameter = "" in the Action method signature:
Not possible due to .NET version.
Removing all other routes has no effect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果标记是可选的,那么您使用的任何正则表达式约束也必须反映这一点,例如
(foo)?
。I was able to reproduce this issue with ASP.NET MVC 2 on .NET 4 . Then I upgraded to ASP.NET MVC 3 and everything worked as expected. The solution I present above does not work with ASP.NET MVC 2, but it works with ASP.NET MVC 3, so I can only assume this is a bug on v2 that is now fixed in v3.
您可以引用 v2,并在 web.config 上使用它来测试 v3:
If the token is optional then whatever regex constraint you use must also reflect that, e.g.
(foo)?
.I was able to reproduce this issue with ASP.NET MVC 2 on .NET 4 . Then I upgraded to ASP.NET MVC 3 and everything worked as expected. The solution I present above does not work with ASP.NET MVC 2, but it works with ASP.NET MVC 3, so I can only assume this is a bug on v2 that is now fixed in v3.
You can reference v2, and use this on web.config to test with v3:
第二次编辑
匹配 ~/fruit/ 和 ~fruit/apple
匹配 ~/banana/ 和 ~/banana/yellow
第一次编辑
尝试实际将参数设置为操作签名上的可选参数,例如:
string parameter = ""
我没有得到这种行为。正如您所描述的那样,这两条路线都对我有用(如果我在路线中添加“-”,第二条路线会抛出 404,但这是预期的)。您的操作方法签名是什么样的?
我将我的路线(和控制器/视图)设置为如下所示:
我的 Index() 操作如下所示:
2nd EDIT
Matching ~/fruit/ and ~fruit/apple
Matching ~/banana/ and ~/banana/yellow
1st EDIT
Try actually setting the parameter as optional on the action signature, such that:
string parameter = ""
I'm not getting that behavior. Both routes work for me as you're describing them (the second route throws a 404 if I add a "-" to the route, but that's expected). What does your action method signature look like?
I set my route (and controller/view) to look like:
And my Index() action looks like: