2011-12-07 11 views
14

Sto lavorando su un sito ASP.Net MVC 3. La vista maestro _Layout contiene un menu e voglio nascondere alcune delle voci del menu in base se si è connessi e quali ruoli si sono a.ASP.Net MVC Nascondi/Mostra voci di menu in base alla sicurezza

Questo funziona attualmente utilizzando il codice come questo

@if (HttpContext.Current.User.Identity.IsAuthenticated) 
{ 
    <li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> 
    if (HttpContext.Current.User.IsInRole("Reporters")) 
    { 
     <li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li> 
    } 
    if (HttpContext.Current.User.IsInRole("Administrators")) 
    { 
     <li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li> 
     <li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li> 
    } 
} 

mi piacerebbe refactoring questo in qualcosa di più leggibile e si avvicinò con qualcosa di simile

@if ((bool)ViewData["MenuMyLearning"]){<li id="MyLearningTab">@Html.ActionLink("My Learning", "MyLearning", "Learning")</li> }  
@if((bool)ViewData["MenuReports"]){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>} 
@if ((bool)ViewData["MenuDashboard"]){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>} 
@if ((bool)ViewData["MenuAdmin"]){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>} 

originariamente ho aggiunto il seguente alla mia base di pensiero costruttore di controllo ho potuto impostare il Viewdata per queste proprietà là

012.
ViewData["MenuDashboard"] = User != null && User.Identity.IsAuthenticated && User.IsInRole("Administrators"); 
ViewData["MenuAdmin"] = User != null && User.Identity.IsAuthenticated && User.IsInRole("Administrators"); 
ViewData["MenuReports"] = User != null && User.Identity.IsAuthenticated && User.IsInRole("Reportors"); 
ViewData["MenuMyLearning"] = User != null && User.Identity.IsAuthenticated; 

Tuttavia, l'oggetto Utente è nullo a questo punto del ciclo di vita. Ho anche provato a creare un filtro globale personalizzato ma il ViewData non è quindi accessibile.

Qual è il modo consigliato di fare qualcosa del genere? Dovrei semplicemente lasciarlo com'era all'inizio con tutto il codice HttpContext nella vista?

+0

Ecco un'altra soluzione http://stackoverflow.com/questions/17012643/role -based-navigation –

risposta

8

Ecco cosa ho fatto. Ho creato una classe di supporto chiamata MenuSecurity con proprietà booleane statiche per ogni voce di menu che mostra quali elementi dovrebbero essere visibili. Ogni proprietà si presentava così

public static bool DashboardVisible 
{ 
    get 
    { 
     return 
     HttpContext.Current.User != null && 
     HttpContext.Current.User.Identity.IsAuthenticated; 
    } 
} 

Poi ho riordinato il mio menu vista parziale a guardare come questo

@if (MenuSecurity.ReportsVisible){<li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li>} 
@if (MenuSecurity.DashboardVisible){<li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li>} 
@if (MenuSecurity.AdminVisible){<li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li>} 
+0

Penso che tu abbia solo 3 gruppi. ma cosa succederà se hai 20 - 30 gruppi? – kbvishnu

9

Informazione generale sui ruoli

Il modo in cui ho fatto questo è quello di creare un principal personalizzato e per memorizzare le informazioni extra richieste in là. Nel tuo esempio, questo includerebbe almeno i ruoli per l'utente. In questo modo si evita di effettuare molti viaggi extra nell'archivio utente (che è probabilmente un database SQL).

avere questa mia domanda a cui do il codice che sto usando con successo uno sguardo un: Is this Custom Principal in Base Controller ASP.NET MVC 3 terribly inefficient?

Nota che sto memorizzando i principal personalizzato nella cache, piuttosto che nella sessione (solo paranoico sul dirottamento di sessione).

Mi piace questo approccio in quanto è molto estensibile. Ad esempio, da allora ho esteso questo per esporre le credenziali di Facebook per quando l'utente accede tramite Facebook.

Basta ricordare che se si memorizzano i dati nella cache è necessario ricordarsi di aggiornarli quando cambia!

risposta alla tua domanda

Giusto per aggiungere, nel vostro caso specifico, probabilmente si dovrebbe memorizzare queste informazioni supplementari in ViewModel e poi il tuo punto di vista sarebbe dire cose come:

@if(ShowReports) { <li id="ReportTab">@Html.ActionLink("Reports", "Index", "Reports")</li> } 
@if(ShowDashboard) { <li id="DashboardTab">@Html.ActionLink("Dashboard", "Dashboard", "Admin")</li> } 
@if(ShowAdmin { <li id="AdminTab">@Html.ActionLink("Admin", "Index", "Admin")</li> } 

con la qualcosa codice ViewModel dicendo come:

public bool ShowReports {get;set;} 
public bool ShowDashboard {get;set;} 
public bool ShowAdmin {get;set;} 

public void SetViewModel() 
{ 
    if (User.Identity.IsAuthenticated) 
    { 
    if (HttpContext.Current.User.IsInRole("Reporters")) 
    { 
     ShowReports = true; 
    } 
    if (HttpContext.Current.User.IsInRole("Administrators")) 
    { 
     ShowDashboard = true; 
     ShowAdmin = true; 
    } 
    } 
} 

io in realtà tendono a prendere questo uno st ep ulteriormente e creare un ReportsLink nel mio ViewModel e impostarlo per contenere il collegamento se l'utente è autorizzato o per essere una stringa vuota se non lo sono. Poi la vista dice semplicemente:

@Model.ReportsLink 
@Model.DashboardLink 
@Model.AdminLink 

In tal caso la parte pertinente del ViewModel potrebbe essere simile a questo:

ReportLink = new MvcHtmlString(HtmlHelper.GenerateLink(HttpContext.Current.Request.RequestContext, System.Web.Routing.RouteTable.Routes, "linktext", "routename", "actionname", "controllername", null, null)); 
+0

Dove si chiama SetViewModel() da ??? – dannyrosalex

Problemi correlati