MVC电子商务路由

时间:2013-07-10 08:52:15

标签: asp.net-mvc-3 asp.net-mvc-4 asp.net-mvc-routing

我正试图了解MVC4的路由

我想创建一个由BrandName / ProductType / PageNumber

组成的URL结构

有时它可能只有品牌或只是产品类型取决于你如何过滤。

e.g。

Store/{BrandName}//{PaginationId} this is unique
Store/{ProductType}/{PaginationId} this is unique
Store/{BrandName}/{ProductType}/{PaginationId}
Store/{ProductType}/BrandName}/{PaginationId}

有任何帮助吗?

感谢

2 个答案:

答案 0 :(得分:2)

您必须注册以下路线:

// 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后,与其匹配的第一条路径将处理该URL。所以必须有一种方法来区分路线。这可以使用约束来完成。约束是一个正则表达式,它决定接收的值是否对参数有效。

假设在第一个映射中,ProductType必须是以“P”开头的东西,您可以添加以下约束:new {productType="P.*"}

  • 如果用户输入以下网址:/ Store / P22 / TheBrand / 12,它将由第一条路线处理
  • 如果用户键入此URL:/ Store / TheBrand / P22 / 12,由于约束,第一条路线不会处理它,但会由第二条路线处理。

你必须消除路线1和1的歧义。 2,还有路线3& 5

如果没有正则表达式可以为您做到这一点,您可以使用一些允许消除它们的额外字符来修改路线,即在产品类型nad品牌名称之前加入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?)。因此它们将自动从查询字符串绑定,如果不存在则保留为null。

没有理由必须使用路由。 您可以使用路由获取“智能”网址,但您不需要。

答案 1 :(得分:0)

创建一个" main"浏览控制器,并将BrandNameProductTypePaginationId作为参数。

结果:

Store/Browse?BrandName=XX&ProductType=YY&PaginationId=ZZ

然后,您可以重叠某些URL-Rewriting logic (link to other SO answer)以获得所需的网址结构。

对于缺少参数的情况,我建议将它们设置为默认值:例如,如果您没有ProductType,则可以执行此操作:

Store/Browse?BrandName=XX&ProductType=ALL&PaginationId=ZZ

简而言之:如果它丢失了,默认它的值并使它成为你所能到处的值。更容易处理,也更容易理解。