5

Come si suppone di visualizzare in modo condizionale le voci di menu in base ai ruoli nel progetto di esempio Bootstrap? Stavo pensando di fare la seguenteVisualizzazione di navigazione basata su ruolo in MVC4 Bootstrap Sample

  1. Implementare INavigatonRouteFilter - in realtà solo l'implementazione del metodo shouldRemove(Route navigationRoutes) - ottenendo il controller/azione predefinita per il percorso e vedere se l'utente è autorizzato
  2. chiamata NavigationRoutes.Filters.Add(myAuthorizationFilter) dopo aver configurato il NavigationRoutes in App_Start

ci sono due problemi che vedo con questo approccio:

  1. Non so come eseguire il primo passaggio a meno che non aggiungo un gruppo di istruzioni condizionali per verificare esplicitamente il nome di Controller
  2. Sembra che potrebbe rendere molto difficile gestire NavigationRoutes.Filters una volta che ci sono molti di filtri o di un desiderio di maggiore modularità in seguito

non so che ho spiegato il problema in modo sufficientemente chiaro, ma fondamentalmente voglio usare ciò che è previsto nel campione Bootstrap per implementare la navigazione l'autorizzazione a base di visualizzazione del menu, se possibile. L'utilizzo di INavigationRouteFilter mi è sembrato il modo più naturale per farlo.

+0

Voglio fare lo stesso, ce l'hai fatta? – Cybercop

+0

@ Biplov13 no, non l'ho ancora, ma ci sto lavorando. Quando arrivo a qualcosa, lo posterò come risposta, ma speravo che qualcun altro lo avesse fatto, così mi sarei sentito come se fossi stato nel modo giusto. –

risposta

5

Per coloro che cercano una risposta o almeno una soluzione rapida. Ecco cosa ho scoperto dopo 5 minuti e non ho certamente alcun effetto collaterale.

routes.MapNavigationRoute<HomeController>("Index", c => c.Index()) 
      .FilterRoute(() => !WebSecurity.IsAuthenticated); 

È possibile fare tutto il vostro filtraggio nella chiamata a FilterRoute() o è possibile aggiungere altri metodi di estensione di risparmiare alcuni caratteri.

Sto pensando .RequireRole ("Adiministratori"); che chiama WebSecurity.RequireRoles() a loro volta (o HttpContext.Current.User.IsInRole()), ecc

public static NavigationRouteBuilder FilterRoute(this NavigationRouteBuilder builder, Func<bool> func) 
    { 
     var currentRoute = builder._parent; 

     NavigationRoutes.Filters.Add(new BootstrapAuthorizationFilter(builder, x => 
     { 
      if (x == currentRoute) 
       return func(); 
      else 
       return false; 
     })); 

     return builder; 
    } 

e BootstrapAuthorizationFilter è solo una classe che implementa INavigationRouteFilter che chiama func() nel suo metodo

ShouldRemove()
public class BootstrapAuthorizationFilter : INavigationRouteFilter 
{ 
    private NavigationRouteBuilder builder; 
    private Func<NamedRoute, bool> func; 

    public BootstrapAuthorizationFilter(NavigationRouteBuilder builder, Func<NamedRoute, bool> func) 
    { 
     this.builder = builder; 
     this.func = func; 
    } 

    public bool ShouldRemove(Route navigationRoutes) 
    { 
     if (navigationRoutes is NamedRoute) 
      return func(navigationRoutes as NamedRoute); 

     return false; 
    } 
} 

Chiaramente niente di strano e non sono sicuro se lo userei in produzione. Ma penso che sia abbastanza semplice e funzioni (per i casi che ho testato). Detto questo, spero che la nuova funzionalità di routing sarà rilasciata a breve :)

+0

Questo è FANTASTICO. Non riesco a capire come modificare questo per i percorsi figlio però. – friggle

+2

Capito. Crea un duplicato del metodo FilterRoute per FilterChildRoute, semplicemente cambiando in "currentRoute = builder._parent.Children.Last()". Quindi modificare GetRoutesForCurrentRequest, dopo "if (filter.ShouldRemove (route)) {...}", inserire "foreach (var childRoute in route.Children.ToArray()) {if (filter.ShouldRemove (childRoute) {route.Children .Remove (childRoute);}} ". Quindi assicurati che FilterChildRoute() sia incatenato direttamente a AddChildRoute() che desideri filtrare. – friggle

+0

+1 per la bella panoramica @Brunner. –

Problemi correlati