5

W jaki sposób powinieneś warunkowo wyświetlać elementy menu na podstawie ról w projekcie Bootstrap Sample? Myślałam o wykonaniem poniższegoWyświetlanie nawigacji opartej na rolach w MVC4 Bootstrap Sample

  1. Wdrożenie INavigatonRouteFilter - naprawdę realizującego sposób shouldRemove(Route navigationRoutes) - dostając domyślnego kontrolera/działanie na trasie i sprawdzając, czy użytkownik jest uprawniony
  2. połączenia NavigationRoutes.Filters.Add(myAuthorizationFilter) po skonfigurowaniu NavigationRoutes w App_Start

Istnieją dwa problemy, które widzę z takim podejściem:

  1. Nie wiem, jak wykonać pierwszy krok, chyba że dodam kilka instrukcji warunkowych, aby sprawdzić nazwę Controller pod kątem jawności.
  2. Wygląda na to, że bardzo trudno będzie sobie z tym poradzić. filtrów lub pragnienie więcej modułowości później

nie wiem, że mam problem wyjaśnił wystarczająco jasno, ale w zasadzie chcę wykorzystać to, co jest zawarte w próbce Bootstrap wdrożyć nawigację autoryzacji opartej wyświetlanie menu, jeśli to możliwe. Korzystanie z tego modelu wydaje się być najbardziej naturalnym sposobem na zrobienie tego.

+0

Chcę zrobić to samo, czy udało się to zrobić? – Cybercop

+0

@ Biplov13 nie, jeszcze nie, ale pracuję nad tym. Kiedy wymyśliłem coś, wyślę to jako odpowiedź, ale miałem nadzieję, że ktoś inny to zrobił, więc czułbym się, jakbym robił to "w odpowiedni sposób". –

Odpowiedz

5

Dla osób szukających odpowiedzi lub przynajmniej szybkiej naprawy. Oto, co wymyśliłem po 5 minutach, a ja na pewno nie mam żadnych skutków ubocznych, które mogą mieć.

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

Można też wykonywać wszystkie twe filtrowanie w wywołaniu FilterRoute() lub można dodać więcej metod przedłużających się zaoszczędzić trochę znaków.

Mam na myśli .RequireRole ("Adiministrators"); który wywołuje WebSecurity.RequireRoles() z kolei (lub HttpContext.Current.User.IsInRole()) itp

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; 
    } 

i BootstrapAuthorizationFilter jest tylko klasa wykonawczych INavigationRouteFilter który wywołuje func() w jego ShouldRemove() metoda

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; 
    } 
} 

Najwyraźniej nic nadzwyczajnego i nie jestem pewien, czy użyłbym go do produkcji. Ale myślę, że jest dość prosty i działa (w przypadkach, które testowałem). Powiedziawszy to, mam nadzieję, że nowa funkcja routingu wkrótce będzie dostępna :)

+0

To jest NIESAMOWITE. Nie wiem, jak to zmienić w przypadku tras dziecięcych. – friggle

+2

Mam to. Wykonaj duplikat metody FilterRoute dla FilterChildRoute, zmieniając po prostu "currentRoute = builder._parent.Children.Last()". Następnie modyfikuj GetRoutesForCurrentRequest, po "if (filter.ShouldRemove (route)) {...}", wstaw "foreach (var childRoute w route.Children.ToArray()) {if (filter.ShouldRemove (childRoute) {route.Children .Remove (childRoute);}} ". Następnie upewnij się, że FilterChildRoute() jest połączony bezpośrednio z AddChildRoute(), który chcesz filtrować. – friggle

+0

+1 dla ładnego przeglądu @Brunner. –

Powiązane problemy