我正在使用MVC4的MvcSiteMapProvider(v4.6.1)来处理面包屑和菜单。我已经完成了有关安装,配置和使用@Html.MvcSiteMap().Menu()
的100级教程。
我现在想要一个显示顶级部分的菜单。目前,我的顶级节点包括Home,Profile,Login,Thing 1,Thing 2和Thing 3.借鉴this SOf answer,我制作了一个菜单,在水平行中显示所有这些项目。我还确定,一旦系统包含授权,无法访问Thing 3的用户就不会在他们的菜单上看到这一点。
但我想要的只是展示一些项目:Home和Login必须显示在面包屑中但不得出现在菜单中。请注意,它们在当前站点地图中不是连续的。
您有什么建议吗?
我目前的观点,从链接的答案批发:
@model MvcSiteMapProvider.Web.Html.Models.MenuHelperModel
@using MvcSiteMapProvider.Web.Html.Models
<div class="nav navbar-nav navbar-left">
<ul class="nav navbar-nav">
@foreach (var node in Model.Nodes) {
<li>@Html.DisplayFor(m => node)</li>
}
</ul>
</div>
我从菜单视图到此视图的当前通话:
@Html.MvcSiteMap().Menu("MenuHelper", 0, true, false, 1)
当然,我可以制作一个新的菜单助手来过滤掉我不想表达的那些。
编辑:Mvc.sitemap:
<mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="MainMenu,!*">
<mvcSiteMapNode title="About" controller="Home" action="About"/>
<mvcSiteMapNode title="Profile" controller="Home" action="UpdateProfile" visibility="MainMenu,!*"/>
<mvcSiteMapNode title="Login" controller="SGAccount" action="Login">
<mvcSiteMapNode title="Register" controller="SGAccount" action="Register">
</mvcSiteMapNode>
</mvcSiteMapNode>
<mvcSiteMapNode title="Thing1" controller="Thing1" action="Index" visibility="MainMenu,!*">
<mvcSiteMapNode title="Thing1-action1" controller="Thing1" action="action1" visibility="RoleMenu,!*"/>
<mvcSiteMapNode title="Thing1-action2" controller="Thing1" action="action2" visibility="RoleMenu,!*"/>
</mvcSiteMapNode>
<mvcSiteMapNode title="Thing2" controller="Thing2" action="Index" visibility="MainMenu,!*">
</mvcSiteMapNode>
</mvcSiteMapNode>
MainMenu显示Home,About,Profile,Login,Thing1和Thing2。它不应该显示所有这些。
编辑2:对外部DI使用结构图,我添加了这一行,但我不确定它是否正确:
x.For<ISiteMapNodeVisibilityProviderStrategy>().Use<SiteMapNodeVisibilityProviderStrategy>();
编辑3:我的面包屑@Html.MvcSiteMap().SiteMapPath()
停止了工作。这也需要修复。
编辑4:我修复了前两个编辑&#39;通过从web.config
删除内部DI设置来解决问题。现在我回过头来展示我想要展示的内容。
答案 0 :(得分:4)
实现此目的的最佳方法是将named HTML helpers与ISiteMapNodeVisibilityProvider一起使用。框中有一个FilteredSiteMapNodeVisibilityProvider,可以通过为每个菜单命名来显示某些菜单实例上的节点。
1)将VisibilityAffectsDescendants设置为false,将默认可见性提供程序设置为FilteredSiteMapNodeVisibilityProvider
<appSettings>
<add key="MvcSiteMapProvider_VisibilityAffectsDescendants" value="false"/>
<add key="MvcSiteMapProvider_DefaultSiteMapNodeVisibiltyProvider" value="MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider"/>
</appSettings>
对于外部DI,这些设置需要由DI容器提供。以下是在StructureMap中如何做到这一点。
// Near the top of the DI module
// (this setting is provided to the constructor of SiteMapBuilderSet)
bool visibilityAffectsDescendants = false;
// Visibility Providers
this.For<ISiteMapNodeVisibilityProviderStrategy>().Use<SiteMapNodeVisibilityProviderStrategy>()
.Ctor<string>("defaultProviderName").Is("MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider");
2)通过sourceMetaData参数
为每个菜单命名@Html.MvcSiteMap().Menu(new { name = "TopMenu" })
@Html.MvcSiteMap().Menu(new { name = "SideMenu" })
@Html.MvcSiteMap().Menu(new { name = "BottomMenu" })
3)按照here所述设置每个节点的可见性属性。请记住,您也可以按HTML帮助程序类型进行过滤。
<mvcSiteMapNode title="Home" controller="Home" action="Index" visibility="TopMenu,BottomMenu,SiteMapPathHelper,!*">
<mvcSiteMapNode title="About" controller="Home" action="About" visibility="SideMenu,BottomMenu,SiteMapPathHelper,!*"/>
<mvcSiteMapNode title="Contact" controller="Home" action="Contact" visibility="TopMenu,SiteMapPathHelper,!*"/>
</mvcSiteMapNode>
如果您有更复杂的可见性规则,您甚至可以implement your own ISiteMapNodeVisibilityProvider。
请注意,可见性也受security trimming影响,但安全修整始终隐藏隐藏节点的所有后代节点。启用安全修整后,每个节点都必须在安全性方面可访问且根据可见性提供程序可见,以便在UI上可见。
如果没有与当前页面匹配的节点,则会自动隐藏基于级别的痕迹路径和菜单。阅读How to Make MvcSiteMapProvider Remember a User's Position以深入了解匹配行为。这仅适用于具有“id”或其他自定义参数的路由。