2012-02-23 44 views
1

我们如何创建一个能够检测到URL匹配路由但是该路由参数错误的路由?ASP.NET MVC路由处理拼写错误的URL?

我已经有几起案件最近在用户已经输错一个URL,它已经很难调试,因为路由表中没有处理这些拼写错误很优雅:

这条路线处理URL /小工具/ GUID

routes.MapRestfulRoute(
    "WidgetsItem", 
    "Widgets/{idString}", 
    new { controller = "Widgets", action = "Item" }, 
    new { idString = 
    @"^[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}$"} 
); 

routes.MapRoute("WidgetsList", "Widgets", new { controller = "Widgets", action = "List" }); 
routes.MapRestfulRoute("CatchAll","{*url}", new {controller = "Error", action = "Http404"}); 

与用户输入的URL /小工具/ 25246810-4b60-4db8-8567-8db8826看起来正确的,但不是(有28只在提供了GUID字符)。

由于URL与路由不匹配,响应为404.但这是欺骗性的,并导致了一个调试问题:它看起来像Widgets/Item操作返回了404。我们花了几个小时试图找出什么这个行为是错误的,事实上这个行为甚至没有被调用。直到我安装了RouteDebugger,我才注意到该GUID格式不正确。

我们如何可以创建将检测到的网址不符合实际的路线,但该参数,以这条路线是错误的另一条错误的路线?

编辑:我可以通过添加匹配/小工具/任何一个新的途径,并把该航线的正常路线后,“固定”它:

routes.MapRestfulRoute(
    "WidgetsItemError", 
    "Widgets/{idString}", 
    new { controller = "Widgets", action = "Item" }, 
    new { idString = @"^.+$" } // match if it has any param at all 
); 

但是,这似乎是非常低效的 - 我会必须为每条路线添加一条类似的错误路线,例如/ Foo,/ Bar/FooBar等等(并且我有很多路线)。没有更通用的方法来做到这一点?

+0

请注意,路由约束可能会伤害您的应用程序性能。 – Paul 2012-02-23 03:30:45

+0

你有任何讨论的链接来支持这个吗?你将如何创建一个没有约束的路由,然后仍然能够区分/ Widgets/guid(返回一个项目)和/ Widgets(返回列表) – 2012-02-23 07:58:32

+0

为什么你要让用户手动输入一个GUID?这很容易出错。 – RickAndMSFT 2012-02-23 19:40:42

回答

0

最简单的解决方法是删除该路由约束,那么您在您的控制器中的空参数,做任何你从这一点希望。

+1

或者在除了约束之外的所有东西之后立即添加另一个路由,然后转到不同的行动。这样你可以保持逻辑分离。 – bhamlin 2012-02-23 02:15:29

+0

@bhamlin - 好点。之后的第二条路线只有在第一条路线失效时才会捕捉到。 – 2012-02-23 02:45:18

+0

已经有不带参数的第2个路线如上图所示:小工具/ GUID负荷的项目,而/小工具(无PARAM)加载列表 – 2012-02-23 02:47:09

2

当我处理GUID在我的路线,我会接受一个字符串,尝试将字符串值解析为GUID,如果它没有解析,我会返回一个不同的视图,表明ID的消息是无效的,并再次尝试

你应该改变这里会删除路由约束和改变你的行动接受一个字符串,而不是一个GUID(除非你的行动已经接受一个字符串)唯一

+1

是的,它实际上已经是一个字符串参数的行为,它已经有一个检查,以确保该字符串是一个有效的GUID。但由于这条路线,它从来没有将其纳入行动。我只是改变了路线来接受任何字符串,并没有更多的问题。 – 2012-02-23 20:53:12

+0

很高兴我能帮上忙。如果它帮助你解决你的问题,请务必将其标记为已接受的答案,谢谢 – 2012-02-24 15:48:56