Domanda

Ho recentemente colpito un blocco stradale cercando di utilizzare il mvcsitemapprovider .

Nella mia applicazione, ho tre aree distinte: atterraggio, applicazione e amministrazione.Attualmente ho implementato il MVCSITEMApprovverider e funziona incredibilmente, ma quello che sto cercando di fare ora - è utilizzare l'helper HTML MvCsitemap e specificare un fornitore di mappe diverse a seconda dell'area in cui sono.

Allora, quando sono:

    .
  • Nell'area "Admin" - Voglio utilizzare il provider denominato "AdminsIteMapprovider".
  • Nell'area "Applicazione" - Voglio utilizzare il provider denominato "AppSiteMapprovider".

    Ho provato quanto segue:

    condiviso -> _aplayout.cshtml

    @Html.Partial("_Menu")
    
    .

    condiviso -> _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>    
        }
    }    
    
    .

    }

    Qualche suggerimento?Non voglio dover copiare / incollare il contenuto _aplayout.cshtml in un nuovo master solo per un'area, preferirei che selezionare il fornitore giusto dinamicamente.

È stato utile?

Soluzione

Aggiungi qualcosa come questo nel tuo file web.config (un nuovo fornitore per ogni 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>
.

Metti questo nella tua masterpage comune (stessa cosa per il 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>
}
.

e finaly Crea un file sitemap per ogni area.

funziona per me.Spero che aiuti.

Altri suggerimenti

Sto usando la versione 4, per i quali apparentemente i fornitori denominati non funzionano. Il modo prescritto per avere più sitemaps in V4 francamente spaventato Il bejeebus da me e era molto più lavoro di quanto volessi.

Per il commento del suggerimento @ Nightwlowlowl888 sulla sua stessa risposta, ho usato l'opzione Named Helphers in V4. Ho ancora un solo file MVC.Sitemap, ma ho opzioni di visibilità reciprocamente esclusive.

Step 1: aggiungi questa impostazione su Web.config

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

Step 2: scegli i nomi dei tuoi diversi "menu" e applicarli all'attributo visibility su ciascun nodo. Nel mio caso avevo "regolare" e "admin". Di nuovo, tutti questi sono nello stesso file 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>
.

Noterai che i report, i download e i collegamenti documenti sono disponibili per utenti regolari e utenti amministratori, ma poiché l'admin utilizza raramente queste opzioni, volevo metterli nel sottomenu Misc.

Step 3: Nel tuo _Layout.cshtml, decidi quale menu si desidera visualizzare.

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

Ho usato questo Bootstrap / Sitemap Tutorial , se non sei penso che puoi chiamare @Html.MvcSiteMap().Menu(new { name = "MENUNAME" })

più sitemaps in un'unica applicazione spiega come questoè fatto in V4, che è cambiato un bel po 'dalla risposta accettata - che era per V3 e prima.

La differenza principale è che ora si configurano più sitemaps sono configurate con DI e è necessario implementare ISITEMAPCacheKeyGenerator e / o ISITemapCachekeyTobuilderseTeckapper, che sono piccole classi da dire a MVCSITEMapprovider come mappare le richieste HTTP in entrata a ciascun sito.

Questo è ciò che ho finito per fare (in base a questa domanda).È un po 'più semplice, spero che aiuti.Ho appena nominato il mio sito map del sito dopo l'area o "predefinito".

<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>
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top