MVCSiteMapProvider 一些节点匹配,其他不匹配
MVCSiteMapProvider some nodes match, others do not
我正在使用 MvcSiteMapProvider
生成面包屑,但我无法将节点与新功能匹配。我们使用 MVC5 区域并使用最新的 MvcSiteMapProvider.MVC5
库。我们将 i18n
与 Resx
文件一起使用,我们的 title
属性是键。我们的页面 URL 在发布后不会更改,因此请使用标准 XML 配置。
我们使用基于 MVC5 属性的路由。
List
动作是家庭控制器和区域的默认动作,Store/
路线也是如此。效果很好,匹配成功。
Search
操作 Store/Search
路由 不 匹配节点。
配置
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0"
xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0 MvcSiteMapSchema.xsd">
<mvcSiteMapNode controller="Dashboard" action="Index" title="Foobar" key="Bar">
<!-- quite a large file -->
<mvcSiteMapNode area="Store" controller="Home" action="List" title="SiteMap_DocumentStore_Home_List" preservedRouteParameters="page, itemsPerPage, msg">
<mvcSiteMapNode area="Store" controller="Home" action="Search" title="SiteMap_DocumentStore_Search" preservedRouteParameters="tags, page"/>
<!-- snip extra entries -->
</mvcSiteMapNode>
</mvcSiteMapNode>
</mvcSiteMap>
感谢我可以从 List
的 mvcSiteMapNode
个子项中删除属性 area
和 controller
。为了完整起见,我将它们留在这里。
家庭控制器
[RouteArea("Store")]
[Route("{action=list}")]
public class HomeController : Controller
{
[Route("{page?}/{itemsPerPage?}")]
public ActionResult List(int page = 1, int itemsPerPage = -1, string msg = "")
{}
[Route("Search/{tags?}/{page?}")]
public ActionResult Search(string tags = "", int page = 1)
{}
}
调查
我感觉这与 List
操作的 MVC 路由 空 有关。如果我将 List
的路线更改为:
[Route("List/{page?}/{itemsPerPage?}")]
public ActionResult List(int page = 1, int itemsPerPage = -1, string msg = "")
{}
然后搜索节点将匹配,它的兄弟节点(我剪掉的)也会匹配
编辑 - 简化路由
我已经删除了控制器的默认路由 [Route("{action=list}")]
。问题依然存在。
问题 #1:
根据 MSDN:
Default Route
You can also apply the [Route] attribute on the controller level, capturing the action as a parameter. That route would then be applied on all actions in the controller, unless a specific [Route] has been defined on a specific action, overriding the default set on the controller.
在你的情况下,默认的控制器级路由将被完全忽略,因为在每种情况下你都有一个覆盖它的操作级路由。
问题 #2:
我通过在 VS 2015 中启动一个新的 MVC 5 项目并添加一个区域和其余配置来研究它“不匹配”的原因。有一段时间我很困惑为什么它不起作用。
然后我发现脚手架为 /Area/<area name>/Views/_ViewStart.cshtml
中的每个区域连接了不同的布局页面。
@{
Layout = "~/Areas/Store/Views/Shared/_Layout.cshtml";
}
我将其更改为使用共享 ViewStart.cshtml
文件,然后它显示了面包屑路径。
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
问题 #3:
另外,您保存的路由参数有问题。由于它们始终派生自当前请求,因此内部请求必须始终提供其祖先的所有参数。此外,参数在父项和子项之间不得具有不同的含义,因此例如 page
必须针对 List
和 Search
引用同一页面。换句话说,每个键名在其祖先中必须是唯一的。
如果它们相同,您只需将附加参数添加到搜索即可解决此问题 URL。
[Route("Search/{page?}/{itemsPerPage?}/{tags?}")]
否则你应该给每个 page
参数一个不同的名称。
请参阅 How to make MvcSiteMapProvider Remember a User's Position 和随附的演示以获取指导。
我正在使用 MvcSiteMapProvider
生成面包屑,但我无法将节点与新功能匹配。我们使用 MVC5 区域并使用最新的 MvcSiteMapProvider.MVC5
库。我们将 i18n
与 Resx
文件一起使用,我们的 title
属性是键。我们的页面 URL 在发布后不会更改,因此请使用标准 XML 配置。
我们使用基于 MVC5 属性的路由。
List
动作是家庭控制器和区域的默认动作,Store/
路线也是如此。效果很好,匹配成功。
Search
操作 Store/Search
路由 不 匹配节点。
配置
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0"
xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0 MvcSiteMapSchema.xsd">
<mvcSiteMapNode controller="Dashboard" action="Index" title="Foobar" key="Bar">
<!-- quite a large file -->
<mvcSiteMapNode area="Store" controller="Home" action="List" title="SiteMap_DocumentStore_Home_List" preservedRouteParameters="page, itemsPerPage, msg">
<mvcSiteMapNode area="Store" controller="Home" action="Search" title="SiteMap_DocumentStore_Search" preservedRouteParameters="tags, page"/>
<!-- snip extra entries -->
</mvcSiteMapNode>
</mvcSiteMapNode>
</mvcSiteMap>
感谢我可以从 List
的 mvcSiteMapNode
个子项中删除属性 area
和 controller
。为了完整起见,我将它们留在这里。
家庭控制器
[RouteArea("Store")]
[Route("{action=list}")]
public class HomeController : Controller
{
[Route("{page?}/{itemsPerPage?}")]
public ActionResult List(int page = 1, int itemsPerPage = -1, string msg = "")
{}
[Route("Search/{tags?}/{page?}")]
public ActionResult Search(string tags = "", int page = 1)
{}
}
调查
我感觉这与 List
操作的 MVC 路由 空 有关。如果我将 List
的路线更改为:
[Route("List/{page?}/{itemsPerPage?}")]
public ActionResult List(int page = 1, int itemsPerPage = -1, string msg = "")
{}
然后搜索节点将匹配,它的兄弟节点(我剪掉的)也会匹配
编辑 - 简化路由
我已经删除了控制器的默认路由 [Route("{action=list}")]
。问题依然存在。
问题 #1:
根据 MSDN:
Default Route
You can also apply the [Route] attribute on the controller level, capturing the action as a parameter. That route would then be applied on all actions in the controller, unless a specific [Route] has been defined on a specific action, overriding the default set on the controller.
在你的情况下,默认的控制器级路由将被完全忽略,因为在每种情况下你都有一个覆盖它的操作级路由。
问题 #2:
我通过在 VS 2015 中启动一个新的 MVC 5 项目并添加一个区域和其余配置来研究它“不匹配”的原因。有一段时间我很困惑为什么它不起作用。
然后我发现脚手架为 /Area/<area name>/Views/_ViewStart.cshtml
中的每个区域连接了不同的布局页面。
@{
Layout = "~/Areas/Store/Views/Shared/_Layout.cshtml";
}
我将其更改为使用共享 ViewStart.cshtml
文件,然后它显示了面包屑路径。
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
问题 #3:
另外,您保存的路由参数有问题。由于它们始终派生自当前请求,因此内部请求必须始终提供其祖先的所有参数。此外,参数在父项和子项之间不得具有不同的含义,因此例如 page
必须针对 List
和 Search
引用同一页面。换句话说,每个键名在其祖先中必须是唯一的。
如果它们相同,您只需将附加参数添加到搜索即可解决此问题 URL。
[Route("Search/{page?}/{itemsPerPage?}/{tags?}")]
否则你应该给每个 page
参数一个不同的名称。
请参阅 How to make MvcSiteMapProvider Remember a User's Position 和随附的演示以获取指导。