【问题标题】:MVC 3 Fall-through routingMVC 3 直通路由
【发布时间】:2012-04-05 12:48:04
【问题描述】:

很抱歉问了一个很n00b 的问题,我对 ASP.NET MVC 很陌生。 我的问题如下:

我希望我的网站按以下方式处理 URL:

www.mysite.com/homepage/name

我希望上面的链接转到该用户的个人资料。为简单起见,控制器将是带有 Test 操作的 Homepage 控制器。

意味着 global.asax 路由将是:

routes.MapRoute(
            "test",
            "homepage/{name}",
            new { controller = "Homepage", action = "Test" }
            );

到目前为止,代码运行良好(我已经对其进行了测试,并且可以正常运行)。

但现在我想要启用的其他功能是:

www.mysite.com/homepage/action/id

工作也是如此。

此路由将是:

routes.MapRoute(
            "Default",
            "homepage/{action}/{id}",
            new { controller = "Homepage", action = "Index", id = UrlParameter.Optional }
        );

问题是当用户想要为某个操作省略 {id} 时会发生什么,路由表检测到该操作名称实际上是 {name} 参数。

有没有办法先检查一个动作是否存在。并且只有在没有的情况下,才将其用作不同路由的参数。

有意义吗?如果没有,我会添加更多细节。

谢谢!

编辑

所以我已经设法使用约束正则表达式解决了这个问题 我在我的控制器中放置了一个定义所有动作的正则表达式:

routes.MapRoute(
           "homepage",
           "homepage/{action}/{id}",
           new { controller = "Homepage", action = "Index", id = UrlParameter.Optional },
           new { action = "(action1|action2|action3)" }
           );

然后是下一条规则:

routes.MapRoute(
            "feed",
            "homepage/{id}",
            new { controller = "Homepage", action = "Test"}
            );

我工作正常,只是很难在此基础上进行扩展。您需要记住将控制器上的每个新操作都放在此处的字符串中。这是调试噩梦的巨大机会。

谢谢!

【问题讨论】:

  • 如果用户创建了一个名为 Index 的帐户,或者您的操作名称是什么?
  • 我猜这一切都需要与数据库管理同步。这是一个很好的问题。我们这样做的方式是自己生成这些 slug,因此我们有权保留一些字符串。
  • 我想我的观点是,通过使用不同的路径来设计东西真的更好,这样就不会发生这样的混乱。

标签: asp.net asp.net-mvc-3


【解决方案1】:

由于 ASP.NET MVC 从RouteTable 中选择第一个匹配当前请求的路由,您应该能够通过更改 Global.asax 中路由的顺序来解决此问题。

首先是这个:

routes.MapRoute(
            "Default",
            "homepage/{action}/{id}",
            new { controller = "Homepage", action = "Index", id = UrlParameter.Optional }
        );

然后是这个:

routes.MapRoute(
            "test",
            "homepage/{name}",
            new { controller = "Homepage", action = "Test" }
            );

希望这会有所帮助。

【讨论】:

  • 这种方式永远不会到达第二条路线。您应该在action 上使用约束以仅允许actions 的特定列表
  • 没用。它仍然尝试将“id”字段解析为操作并返回 404 not found。
【解决方案2】:

你需要先放Default路由,同时还要限制它的允许值

routes.MapRoute(
            "Default",
            "homepage/{action}/{id}",
            new { controller = "Homepage", action = "Index", id = UrlParameter.Optional },
            new {action = @"Index|Delete|Add"}
        );

routes.MapRoute(
            "test",
            "homepage/{name}",
            new { controller = "Homepage", action = "Test" }
            );

这样,只有当动作值与约束中提供的值匹配时,才会使用第一个路由,否则它将移动到下一个规则。

您还必须确保在创建用户配置文件时,任何名称都不应与您支持的 default 路由操作之一匹配。

【讨论】:

  • 谢谢。当我编辑了帖子时,它可以工作。但很难扩展。非常感谢!
  • @Omer,如果您想 on-the-fly 检查该操作是否存在,请查看来自How to make sure controller and action exists before doing redirect, asp.net mvc3 的 frenky 的答案
  • 看起来不错。有没有可能减慢我的路由速度?这里有效率损失吗?
  • @omer,我不知道..也许你可以评论他的回答并问他..(或者关于它的新问题
猜你喜欢
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
相关资源
最近更新 更多