【问题标题】:Is it possible to pass page numbers that will rery on the route segment location?是否可以传递将依赖于路线段位置的页码?
【发布时间】:2012-03-24 13:20:56
【问题描述】:

假设我将以下 URL 请求传递给路由系统,这是可能的最长 URL。

商店/商店内容/宠物/猫/食物/1

其中“1”是页码,pets是根指针

现在我的路线条目如下所示:

    routes.MapRoute(
    "StoreContent", // Route name
    "{controller}/{action}/{rootpointer}/{category}/{category2}/{page}", // URL with parameters
    new { rootpointer = UrlParameter.Optional, category= UrlParameter.Optional, category2 =     UrlParameter.Optional, page = UrlParameter.Optional},
new { controller = "Store", action = "StoreContent" });

我的方法是这样的:

public PartialViewResult StoreContent(string rootpointer, string category, string category2, int page) {}

问题是,当我传递类似 store/storecontent/pets/1 这样的 URL 时,类别会被分配“页面”值,这是可以理解的,因为页面现在位于保留的路由段的位置对于类别和路由系统无法判断哪个值属于页面以及哪个属于类别,因为这些是匿名类型。

有什么办法可以解决这个问题,我知道这可以通过使用 catchall 并解析它来提取值来手动完成,但是有没有更优雅的解决方案,不需要任何手动干预?如果我的 URL 反映了它,我也可能只使用类似 /page-{page}/ 的东西,那么路由系统应该为页面匿名类型选择它并将其值正确分配给方法上的页面参数?

【问题讨论】:

  • /{controller}/{action}/{rootpointer}/{categories}/{page} 用连字符划分类别呢?

标签: c# asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-routing


【解决方案1】:

这不是路由的工作方式

如果您将路线定义为

{controller}/{action}/{rootpointer}/{category}/{category2}/{page}

然后使用store/storecontent/pets/1访问你的页面,那么你的路由参数如下:

  • 控制器 = 商店
  • 动作 = 商店内容
  • 根指针 = 宠物
  • 类别 = 1
  • category2 = null
  • page = null

您尝试做的实际上是 store/storecontent/pets///1,但您无法提供此类网址

REST 风格的?

这也不是 RESTful。为什么?因为提供页面作为 URL 的一部分会返回可以说不确定的结果...

这就是为什么分页和排序应该(在 REST 方面)作为查询变量提供,如 store/storecontent/pets?page=1。这当然会奏效。它们成为与路由本身无关的任意变量。试试这是否也适用于您的路线定义,因为它可能也适用,因为您的许多路线段都是可选的。

可能的解决方案 1

可能的解决方案(尽管我建议您将分页保留为查询变量)是定义多个路由:

{controller}/{action}/{page}
{controller}/{action}/{rootpointer}/{page}
{controller}/{action}/{rootpointer}/{category}/{page}
{controller}/{action}/{rootpointer}/{category}/{category2}/{page}

其中每一个都需要对page = "\d+" 进行限制,因此路由会一直进行下去,直到命中正确的一个。

可能的解决方案 2

通过将页面保留为单独的查询参数,没有人说您不能将其定义为默认值的一部分:

routes.MapRoute(
    "Some route",
    "{controller}/{action}/{rootpointer}/{category}/{category2}",
    new {
        rootpointer = UrlParameter.Optional,
        category= UrlParameter.Optional,
        category2 = UrlParameter.Optional,
        page = 1
    }
);

如您所见,我为页面提供了默认值。我知道您已将其设置为可选,但我在这里要说的是您可以为非路由相关值提供默认值。例如查询变量。

补充观察

如果您为控制器和操作提供单值常量约束,则无需像您那样将它们作为路由值保留在路由定义中。您目前定义的当前路线会更好:

routes.MapRoute(
    "StoreContent", // Route name
    "Store/StoreContent/{rootpointer}/{category}/{category2}/{page}", // URL with parameters
    new {
        controller = "Store",
        action = "StoreContent",
        rootpointer = UrlParameter.Optional,
        category = UrlParameter.Optional,
        category2 = UrlParameter.Optional,
        page = UrlParameter.Optional
    }
    // no need for constraints
);

【讨论】:

    【解决方案2】:

    您需要在页面变量上添加另一个路由和正则表达式约束

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 2012-07-03
      • 2016-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多