是否可以使用 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
的东西
但我也想处理像
这样的网址
http://example.com/posts/archives/2014/
,
http://example.com/posts/archives/2014/12/page/3
, -
http://example.com/posts/archives/2014/page/3
我尝试在下面添加路线:
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/12
和 http://example.com/posts/archives/2014
,因为月份是可选的。如果未提供,它还将页码默认为 1,月份默认为 0。
我有这条路线:
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
但我也想处理像
这样的网址http://example.com/posts/archives/2014/
,http://example.com/posts/archives/2014/12/page/3
, -http://example.com/posts/archives/2014/page/3
我尝试在下面添加路线:
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/12
和 http://example.com/posts/archives/2014
,因为月份是可选的。如果未提供,它还将页码默认为 1,月份默认为 0。