您必须注册以下路线:
// 1: Store/ProductType/BrandName/PaginationId
// (all parts must exists in the URL)
routes.MapRoute("ProductType", "Store/{productType}/{brandName}/{paginationId}",
new { controller = "Store", action = "Index" },
new { /* constraints */ });
// 2: Store/BrandName/ProductType/PaginationId
// 3: Store/BrandName/ProductType
// 4: Store/BrandName
// (both productType and paginationId can be missing)
routes.MapRoute("BrandProduct", "Store/{brandName}/{productType}/{paginationId}",
new { controller = "Store", action = "Index",
productType = UrlParameter.Optional,
paginationId = UrlParameter.Optional},
new { /* constraints */ });
// 5: Store/ProductType/PaginationId
// (all parts must exists in the URL)
routes.MapRoute("ProductType", "Store/{productType}/{paginationId}",
new { controller = "Store", action = "Index",
brandName = 0, paginationId = 0},
new { /* constraints */ });
// Action Index should have 3 parameters: brandName, productType and paginationId
// brandName, productType and paginationId should be nullable
// or reference type (class) to accept nulls
当接收到一个 URL 时,匹配它的第一个路由将处理它。所以必须有一种方法来区分路线。这可以使用约束来完成。约束是一个正则表达式,它决定接收到的值是否对参数有效。
假设在第一个映射中 ProductType 必须以“P”开头,您将添加此约束: new {productType="P.*"}
:
- 如果用户键入这个 URL:/Store/P22/TheBrand/12,它将被第一个路由处理
- 如果用户键入这个 URL:/Store/TheBrand/P22/12,由于约束,它不会被第一个路由处理,而是由第二个路由处理。
您必须区分路线 1 和 2,以及路线 3 和 5
如果没有正则表达式可以为您做到这一点,您可以使用一些额外的字符来修改路线,以便消除它们的歧义,即将 P- 和 B- 放在产品类型和品牌名称之前,如下所示:
// 1:
routes.MapRoute("ProductType", "Store/P-{productType}/B-{brandName}/{paginationId}",
// 2, 3, 4
routes.MapRoute("BrandProduct", "Store/B-{brandName}/P-{productType}/{paginationId}",
请记住,路由的处理顺序与它们注册的顺序相同。
编辑 - 对 OP 评论的回答:
如果您只想要类似于 ASP.NET 的行为,其中单个页面使用所有信息,请使用此映射:
routes.MapRoute("Store", "Store", new {controller="Store",action="Index"}}
使用此映射,所有额外信息将最终出现在查询字符串中,如下所示:
http://mysite/Store?ProductType=xxx&BrandName=yyy&PaginationId=23
如果您不提供某些参数,它们将被简单地从查询字符串中省略。
操作如下所示:
Index(string brandName, string prouctType, int? paginationId)
请注意,由于所有参数都是可选的,因此它们必须是可空的(引用类型如string
或可空值类型如int?
)。因此它们将自动从查询字符串中绑定,或者如果不存在则保留为空。
没有理由必须使用路由。您可以使用路由来获取“智能”网址,但您不需要这样做。