是否可以使用 MVC 中的单个路由来匹配所有这些 url?

Can a single route in MVC be used to match all these urls?

我有这条路线:

routes.MapRoute(
      name:="Archives",
      url:="posts/archives/{year}/{month}",
      defaults:=New With {.controller = "Posts", .action = "Archives", .year =
      UrlParameter.Optional, .month = UrlParameter.Optional})

这行得通,所以我得到了类似 http://example.com/posts/archives/2014/12

的东西

但我也想处理像

这样的网址

我尝试在下面添加路线:

  routes.MapRoute(
       name:="ArchivesWithPaging",
       url:="posts/archives/{year}/{month}/page/{page}",
       defaults:=New With {.controller = "Posts", .action = "Archives", .year =
       UrlParameter.Optional, .month = UrlParameter.Optional,
      .page = UrlParameter.Optional})

然后导致http://example.com/posts/archives/2014/12变成http://example.com/posts/archives/2012/12/page

那么是否有一条路线可以捕获所有这些,还是我需要多条路线?

或者,如果一条路线不可能,哪些路线可以帮助我正确匹配这些情况?

准确回答您的问题:是的,您可以使用一条路线来匹配所有这些 URL。您可以 implement RouteBase in a custom class 并准确处理您想要的路线,并且 return 对于您不想在该路线中处理的任何 URL 为 null。

但是,对于这个简单的场景,您不必走这么极端。要处理这种情况下的所有情况,您实际上需要 3 条路线 - 一条用于标准 URL,一条用于带分页的标准 URL,一条用于没有月份的 URL分页。

不过,您确实需要确保它们以正确的顺序列出,否则它们将无法按预期运行。路由通常应按从最具体到最不具体的顺序列出,首先注意左侧的值到右侧的值。

对于您最具体的路线,除了月份之外,我认为将任何其他内容设为可选没有多大意义。使用 UrlParameter.Optional 等同于使用空字符串,如果您的控制器期望这些是整数,这将是有问题的。你没有指定你想要的字符串,所以我在这个例子中假设整数:

Public Class PostsController
    Inherits System.Web.Mvc.Controller

    Function Archives(year As Integer, month As Integer, page As Integer) As ActionResult
        Return View()
    End Function

End Class

下面是按从最具体到最不具体的顺序列出的路线:

routes.MapRoute(
    name:="ArchivesYearWithPaging", _
    url:="posts/archives/{year}/page/{page}", _
    defaults:=New With {.controller = "Posts", .action = "Archives", .month = 0})

routes.MapRoute(
    name:="ArchivesWithPaging", _
    url:="posts/archives/{year}/{month}/page/{page}", _
    defaults:=New With {.controller = "Posts", .action = "Archives"})

routes.MapRoute(
    name:="Archives", _
    url:="posts/archives/{year}/{month}", _
    defaults:=New With {.controller = "Posts", .action = "Archives", .page = 1, .month = 0})

解释:

第一条路线是处理http://example.com/posts/archives/2014/page/3。它将 0 作为默认月份传递给 Archives 控制器操作方法,因此当 URL 未指定月份时您可以轻松识别。

第二条路线是处理http://example.com/posts/archives/2014/12/page/3。如果你不使用约束(而且你真的没有理由必须在这里),它必须遵循第一条路线,因为月份参数可能会无意中匹配 /page/ 段。

第三条路线将处理 http://example.com/posts/archives/2014/12http://example.com/posts/archives/2014,因为月份是可选的。如果未提供,它还将页码默认为 1,月份默认为 0。