I've recently hit a road block trying to use the MvcSiteMapProvider.
In my application, I have three distinct areas: Landing, Application and Administration. I currently have implemented the MvcSiteMapProvider and it works amazingly, but what I'm trying to do now - is use the Html MvcSiteMap Helper and specify a different map provider depending on the area that I'm in.
So, when I'm:
I've tried the following:
Shared -> _AppLayout.cshtml
@Html.Partial("_Menu")
Shared -> _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>
}
}
}
Any suggestions? I don't want to have to copy/paste the _AppLayout.cshtml content into a new master just for one area, I'd rather it select the right provider dynamically.
Add something like this in your web.config file (a new provider for each area):
<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>
Put this in your common masterpage (same thing for the menu):
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>
}
And finaly create a sitemap file for each area.
It works for me. Hope it helps.