2012-02-24 20 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