2010-02-04 17 views
15

Ho visto alcune domande simili, ma nessuna che assomiglia a quello che sto cercando di fare.Creazione di un menu Pagina principale ASP.NET MVC Dinamicamente, in base al "Ruolo" dell'utente corrente

Questo è il mio attuale implementazione w/out alcuna sicurezza:

<div id="menucontainer"> 
    <ul id="menu">    
     <li><%= Html.ActionLink("Main List", "Index", "AController")%></li> 
     <li><%= Html.ActionLink("Product List", "Index", "BController")%></li> 
     <li><%= Html.ActionLink("Company List", "Index", "CController")%></li> 
     <li><%= Html.ActionLink("User List", "Index", "DController")%></li> 
    </ul> 
</div> 

Questo va bene, e le opere di cui sopra. Ho impostato [Autorizza] Attributi su Azioni per CController e DController per impedire l'accesso non autorizzato - ma vorrei rimuovere quegli elementi dal menu per gli utenti che non hanno il ruolo corretto, perché quando lo vedono e fanno clic su di esso e dice loro che non hanno il permesso, lo vorranno. Se non sanno che è lì, è meglio per tutte le persone coinvolte ...

Qualcosa di simile è in definitiva l'obiettivo che sto cercando di ottenere, ma sto cercando l'aproach più MVC Flavored, dove la "vista" è "stupido":

<div id="menucontainer"> 
    <ul id="menu">    
     <li><%= Html.ActionLink("Main List", "Index", "AController")%></li> 
     <li><%= Html.ActionLink("Product List", "Index", "BController")%></li> 
     <% If(Role = Roles.Admin) { %> 
     <li><%= Html.ActionLink("Company List", "Index", "CController")%></li> 
     <li><%= Html.ActionLink("User List", "Index", "DController")%></li> 
     <% } %> 
    </ul> 
</div> 
+0

Io sono ... penso. Ci sono due livelli di utente, normale e amministratore. Solo gli admin possono vedere gli elenchi Company e User, gli attributi [Authorize] sul controller impediscono l'accesso non autorizzato, ma voglio nascondere la vista ai non-Admin in modo che non abbiano nemmeno l'idea che siano lì nella loro testa. – Nate

risposta

15

ho fatto qualcosa di simile:

  • utilizzare una classe base comune per i miei controllori ('strato supertype')
  • nel BaseController, ignorare OnActionExecuted (si potrebbe anche definire un attributo ActionFilter per questo)

Qualcosa di simile a questo:

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     // build list of menu items based on user's permissions, and add it to ViewData 
     IEnumerable<MenuItem> menu = BuildMenu(); 
     ViewData["Menu"] = menu; 
    } 

Nella pagina master:

<% var model = ViewData["Menu"] as IEnumerable<MenuItem>; %> 
    <% Html.RenderPartial("Menu", model); %> 

(Nota: in realtà, ho un MasterViewModel che contiene tra gli altri il modello di menu)

+0

Suppongo che ActionExecutedContext abbia informazioni sull'utente corrente? e ho semplicemente bisogno di aggiornare tutti i miei controller per ereditare da questo nuovo controller di base che ho definito? – Nate

+1

sì, ActionExecutedContext ti dà accesso a a.o. the HttpContext – jeroenh

+2

@jeroenh: cos'è a.o. ? – Pretzel

2

sei venuto a conoscenza MvcContrib s' MenuBuilder?

In caso contrario, suggerisco di dare un'occhiata a questo. Il progetto di esempio UI è un buon modo per iniziare a imparare come usarlo.

0

Come @SD", ha detto, è possibile creare un "aiuto lucido" che con o rendere il collegamento, o meno, in base ai requisiti di sicurezza.

Ecco una buona lettura su aiutanti personalizzati (verso il basso):

understanding-html-helpers on S. Walther's blog

1

Di solito mi basta controllare il ruolo in un modo simile che hai fatto e poi o rendere una vista parziale con i collegamenti o semplicemente crearli. Qualcosa di simile usando la sintassi del rasoio. Io uso T4MVC per le azioni.

@if(User.IsInRole("Admin")) 
{ 
    <li><a href="@Url.Action(MVC.Admin.User.Index())">Users</a></li> 
} 

Per motivi di sicurezza, utilizzo Fluent Security. Spero che questo aiuti.

2

Nessuno menziona MvcSiteMapProvider che fa questo e può essere facilmente integrato nel progetto di Visual Studio utilizzando NuGet.

0

La soluzione di Joe è stata di gran lunga la più semplice e ha funzionato per me. Ho pagine presenti in aree separate per le quali ho bisogno di configurare rapidamente un sistema di menu che reagisce e funziona in base a quale area è presente l'utente.Anche nel mio caso non ci sono collegamenti tra le aree nel mio sistema, quindi vado al prossimo configure multiple sitemaps for the MvcSiteMapProvider.

Spero che questo aiuti chiunque altro alla ricerca di una soluzione semplice ed efficace!

Problemi correlati