2012-02-24 76 views
8

我最近碰到一个试图使用MvcSiteMapProvider的路障。使用多个MvcSiteMaps

在我的应用程序中,我有三个不同的方面:着陆,应用程序和管理。我目前已经实现了MvcSiteMapProvider,它的工作原理非常惊人,但我现在要做的是使用Html MvcSiteMap Helper,并根据我所在的区域指定不同的地图提供者。

因此,当我是:

  • 在“管理”区域 - 我想使用名为“AdminSiteMapProvider”的提供程序。
  • 在“应用程序”区域 - 我想使用名为“AppSiteMapProvider”的提供程序。

我已经试过如下:

共享 - > _AppLayout.cshtml

@Html.Partial("_Menu") 

共享 - > _Menu.cshtml

@{ 
if (HttpContext.Current != null && HttpContext.Current.Handler is System.Web.Mvc.MvcHandler) 
{ 
    var handler = HttpContext.Current.Handler as System.Web.Mvc.MvcHandler; 
    var currentArea = handler.RequestContext.RouteData.Values["area"] ?? string.Empty; 
    if (!string.IsNullOrEmpty(currentArea.ToString())) 
    { 
     <text>@Html.MvcSiteMap("AppSiteMapProvider").Menu()</text> 
    } 
    else if (currentArea.ToString() == "Admin") 
    { 
     <text>@Html.MvcSiteMap("AdminSiteMapProvider").Menu()</text>  
    } 
}  

}

任何建议?我不想将_AppLayout.cshtml内容复制/粘贴到一个新区域,只是为了一个区域,我宁愿动态地选择正确的提供程序。

+0

您是否尝试过使用mvcSiteMapNode的区域属性? 2012-02-27 13:48:26

+0

这只会改变生成的链接(我目前使用“area”作为管理链接)。我期望生成一组完全不同的链接,这些链接字面上位于单独的文件(admin.sitemap)中,具体取决于我目前是否在“管理”区域中进行浏览。 – Kori 2012-02-27 14:21:19

回答

8

添加这样的事情在你的web.config文件(每个区域一个新的供应商):

var currentArea = (string)ViewContext.RouteData.DataTokens["area"]; 
if (string.IsNullOrWhiteSpace(currentArea)) 
{ 
    <text>@Html.MvcSiteMap("AppSiteMapProvider").SiteMapTitle()</text> 
} 
else if (currentArea.ToString() == "Admin") 
{ 
    <text>@Html.MvcSiteMap("AdminSiteMapProvider").SiteMapTitle()</text> 
} 

<siteMap defaultProvider="AppSiteMapProvider" enabled="true"> 
    <providers> 
    <clear /> 
    <add name="AppSiteMapProvider" type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" siteMapFile="~/Mvc.Sitemap" securityTrimmingEnabled="true" cacheDuration="5" enableLocalization="true" scanAssembliesForSiteMapNodes="true" includeAssembliesForScan="" excludeAssembliesForScan="" attributesToIgnore="visibility" nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider" controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider" actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider" aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider" siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider" siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider" siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" /> 
    <add name="AdminSiteMapProvider" type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider" siteMapFile="~/Areas/Admin/Mvc.Sitemap" securityTrimmingEnabled="true" cacheDuration="5" enableLocalization="true" scanAssembliesForSiteMapNodes="true" includeAssembliesForScan="" excludeAssembliesForScan="" attributesToIgnore="visibility" nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider" controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider" actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider" aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider" siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider" siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider" siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" /> 
    </providers> 
</siteMap> 

在共同母版(用于菜单同样的事情)将这个

最后为每个区域创建一个站点地图文件。

它适用于我。希望能帮助到你。

+1

啊,完美的作品。谢谢:) – Kori 2012-02-28 15:55:32

2

这就是我最终做的(基于这个问题)。这有点简单,希望它有帮助。我刚刚在该区域之后命名了我的站点地图提供程序,或“默认”。

<ul id="menu"> 
@{ 
    // gets a different sitemap for each area (or the default one) 
    var _siteMap = ViewContext.RouteData.DataTokens["area"] 
         as string ?? "Default"; 
    var sm = Html.MvcSiteMap(_siteMap); 
    @sm.Menu(sm.Provider.RootNode, true, true, 2); 
} 
</ul> 
5

Multiple Sitemaps in One Application解释了这是如何V4,这已经改变,从公认的答案颇有几分做 - 这对V3和之前。

的主要区别是,现在多个Sitemap与DI配置,您需要实现ISiteMapCacheKeyGenerator和/或ISiteMapCacheKeyToBuilderSetMapper,这是小班告诉MvcSiteMapProvider如何将传入的HTTP请求到每个网站导航地图。

+1

DI蝙蝠侠的神圣母亲,有没有简单的方法来使用两个站点地图文件? – Jack 2014-02-28 03:47:24

+1

对不起,罗宾,目前还没有。虽然,现在有更多的解决方法,比如使用具有高级可见性的“命名”HTML助手,因此在很多情况下不需要它们。 – NightOwl888 2014-02-28 04:41:41

+0

谢谢 - 我最终只使用一个。实际情况是,其他网站地图仅仅是一个“主页,关于,联系人,常见问题解答”,这是前瞻性的,每个人都可以看到。没有理由为此的网站地图。 – Jack 2014-03-03 17:54:39

5

我正在使用版本4,对于这些版本,提供者显然不起作用。 prescribed way to have multiple sitemaps in v4坦白地吓了我一跳,并且比我想象的要多得多。

根据@ NightOwl888对他自己的答案的建议评论,我使用了v4中的命名助手选项。我仍然只有一个mvc.sitemap文件,但我有互斥的可见性选项。

第1步:将此设置添加到网络中。配置

<add key="MvcSiteMapProvider_DefaultSiteMapNodeVisibiltyProvider" value="MvcSiteMapProvider.FilteredSiteMapNodeVisibilityProvider, MvcSiteMapProvider"/> 

2步:选择你的不同的“菜单”的名称,并将其应用到每个节点上的visibility属性。在我的情况下,我有“常规”和“管理员”。再次,所有这些都在相同的mvc.sitemap文件中。

<mvcSiteMapNode title="Reports" controller="Report" action="List" visibility="Regular,!*"/> 
<mvcSiteMapNode title="Downloads" controller="Download" action="List" visibility="Regular,!*"/> 
<mvcSiteMapNode title="Documents" controller="Document" action="List" visibility="Regular,!*"/> 

<mvcSiteMapNode title="Users" controller="User" action="List" visibility="Admin,!*"/> 
<mvcSiteMapNode title="Projects" controller="Project" action="List" visibility="Admin,!*"/> 
<mvcSiteMapNode title="Misc" clickable="false" visibility="Admin,!*"> 
    <mvcSiteMapNode title="Reports" controller="Report" action="List" visibility="Admin,!*"/> 
    <mvcSiteMapNode title="Downloads" controller="Download" action="List" visibility="Admin,!*"/> 
    <mvcSiteMapNode title="Documents" controller="Document" action="List" visibility="Admin,!*"/> 
</mvcSiteMapNode> 

你会注意到,这些报告,下载和文档链接适用于使用普通用户和管理员用户,但由于管理员很少使用这些选项,我希望把他们在其它子菜单。

第3步:在_Layout.cshtml中,决定要显示哪个菜单。

@if(User.IsInRole("Admin")) 
{ 
    @Html.MvcSiteMap().Menu("BootstrapMenuHelperModel", false, new { name = "Admin" }) 
} 
else 
{ 
    @Html.MvcSiteMap().Menu("BootstrapMenuHelperModel", false, new { name = "Regular" }) 
} 

我用这个bootstrap/sitemap tutorial,如果你不是我想你可以叫@Html.MvcSiteMap().Menu(new { name = "MENUNAME" })

+2

多么美好而简单的做事方式。我也同意DI方法是过分的,而且非常荒谬。使用你的方法,它对我来说工作得很好。 – TheEdge 2015-06-20 06:06:37