我再次提到我的愚蠢的MVC路由问题。 我正在创建一个电子商务项目,并坚持在路由的一个点。到目前为止,属性路由与以下URL一起正常工作 abc.com/Electronics/Audio/Portable Audio / iPods 以
的形式Category / Subcategory / Subsubcategory / Types / productname {stuck here}
但是现在我需要显示产品名称,在这里我被卡住了。产品可以在任何级别。像
abc.com/Electronics/Apple iPod Nano
abc.com/Electronics/Audio/Apple iPod Nano
abc.com/Electronics/Audio/Portable Audio / Apple iPod Nano
abc.com/Electronics/Audio/Portable Audio / iPods / Apple iPod Nano
问题是如果我定义类别控制器如下:
[Route("{category}/{productname?}")]
public ActionResult Category(string category,string productname)
{
//code
}
和子类别控制器如下
[Route("{category}/{subcategory}/{productname?}")]
public ActionResult Subcategory(string category,string subcategory,string productname)
{
//code
}
等等......
我收到模糊路由的错误,因为在单击子类别的链接后(如果没有产品名称),属性路由再次作为两个参数的条件路由到类别控制器。
那么如何区分这两个控制器呢?或者任何更好的想法总是受欢迎的,因为我几乎是路由和MVC的新手。
另外请告诉我们是否有任何想法可以严格定义要映射的控制器,无论参数是否匹配,但保持URL形式如上所述。
谢谢。
答案 0 :(得分:0)
由于您的所有路段都是可选的,因此您的路线会重叠。
// This will match any URL with 1 or 2 segments
[Route("{category}/{productname?}")]
// This will match any URL with 2 or 3 segments
[Route("{category}/{subcategory}/{productname?}")]
无论您如何申报路线,路线顺序都很重要。但是,由于它们都会匹配一个包含2个网段的网址,因此第一次匹配总是获胜并且当您拥有2段网址时,其中一条路线将始终取消另一条路线并不重要
这种情况有6种方法:
{category}/{productname}
和{category}/{subcategory}/{productname}
不会发生冲突。Audio/{?productname}
代替{category}/{?productname}
。RouteBase
子类。见this example。{*slug}
之类的全能路由,然后在控制器或其中一个服务中处理您的URL逻辑。我认为这个选项是一个黑客,因为你基本上是抛弃窗口并管理控制器内部的URL逻辑而不是它所属的路由框架。如果您事先知道您将拥有的子类别的最大数量,您可以使用单独的操作方法来处理每个段长度。
[Route("{category}")]
public ActionResult Category(string category)
{
}
[Route("{category}/{subcategory1orProductName}")]
public ActionResult CategorySubcategory1(string category, string subcategory1orProductName)
{
// Figure out here whether the last parameter is a subcategory or product name.
}
[Route("{category}/{subcategory1}/{subcategory2orProductName}")]
public ActionResult CategorySubcategory1(string category, string subcategory1, string subcategory2orProductName)
{
// Figure out here whether the last parameter is a subcategory or product name.
}
但我们再一次将路由逻辑放入它不属于的控制器中。
内置路由工具功能强大,可以处理各种场景。但是,他们特别擅长的一件事是将类别/子类别/ contentItem路由构建到未知数量的级别,您需要做一些额外的工作才能到达那里。
在这种情况下,您最好的选择是
RouteBase
覆盖,为类别创建另一个覆盖。将URL段放入数据库表中。使用自联接表构建类别/子类别部件,并将其与类别控制器匹配。使用相同的自联接表来构建类别/子类别/产品,并将其与产品路径中的匹配。确保缓存这些网址,以便每个请求都不会访问数据库,因此当您要将其用于ActionLinks
时,您的路由可以匹配传入的网址并重建网址。