4

我的 ASP.NET MVC3 应用程序中的路由存在一些问题,它确实不能按我的意愿工作。

Global.asax 中的路由定义

routes.MapRoute(
            "News", // Route name
            "{lang}/{controller}/{action}/{page}/{id}", // URL with parameters
            new { lang = "pl", controller = "News", action = "Index", page = 1, id = UrlParameter.Optional } // Parameter defaults
        );

所以我想在两种情况下使用它:

  1. /{lang}/{controller}/{action}/{page}- 转到特定分页的页面
  2. /{lang}/{controller}/{action}/{page}/{id}- 记住当前页面,并转到特定的页面id

生成我使用的链接:

@Html.RouteLink(i.ToString(), "News", new { lang = ViewBag.Lang, page = i })

其中i是页数,lang 是语言。

控制器中,我处理它的女巫动作

public ViewResult Index(string lang, int page = 1)

问题

@Html.RouteLink给了我链接/pl/News/Index/2(当点击“2”时),但我的控制器没有处理它,页面仍然是“1”。因此,当我两次单击相同的链接时,它会给出:/pl/News/Index/2/2然后页面等于“2”。

如果有人可以向我解释它是如何工作的,我能做些什么来解决它?

任何帮助,将不胜感激。

4

2 回答 2

2

我猜您在这里缺少的是路由系统使用当前请求中的变量值来生成出站规则。

例如 - 如果你在页面 /pl/News/Index/2 你有

lang = "pl", controller = "News", action = "Index", page = 2

如果您尝试生成这样的规则

@Html.RouteLink(i.ToString(), "News")

路由系统将使用已经存在的变量,如langpage,并将生成完全相同的 URL - /pl/News/Index/2。

当然,您在 Html.RouteLink 中传入匿名类型的值会被优先处理,并将覆盖当前请求中的值。因此,在您的示例中,您应该考虑生成链接时所在的 URL

优先顺序为:

  1. 匿名类型传递的变量
  2. 请求变量
  3. 路由中定义的默认值。

这部分好像

lang = ViewBag.Lang

是没用的,因为如果您不提供lang将从请求中获取 - 所以它将被保留。

更新(可能不相关):

您还应该记住,如果您有多个匹配规则 - 路由系统将选择一个满足约束的规则(例如,请求中的值不应与默认变量冲突)

更新2

路由系统使用请求变量直到第一个明确指定的变量(通过匿名类型),所以如果您明确指定lang - 不会重用请求变量(在您的情况下,因为lang是您的 url 中的第一段)

于 2012-06-13T07:39:39.433 回答
0

我认为您的部分问题是您有点违反约定,并且由于 MVC 依赖约定来成功路由,因此您的映射有点失败。

我建议像这样重写你的路由:

routes.MapRoute(
            "News", // Route name
            "{controller}/{action}/{lang}/{id}/{page}", // URL with parameters
            new { controller = "News", action = "Index", lang = "pl", page = 1, id = UrlParameter.Optional } // Parameter defaults
        );

URL 最常见的情况似乎是:

http://yourdomainhere/news/pl/some-sort-of-permalink/1
于 2012-06-13T07:42:14.287 回答