2010-02-04 6 views
15

J'ai vu des questions similaires, mais aucune qui ressemble à ce que j'essaie de faire.Création d'un menu ASP.NET MVC Master Page Dynamiquement, basé sur le «rôle» de l'utilisateur actuel

Ceci est mon implémentation actuelle w/toute sécurité:

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

Cela est bien, et les travaux ci-dessus. J'ai l'option [Authorize] Attributes sur les actions pour CController et DController pour empêcher l'accès non autorisé - mais je voudrais supprimer ces éléments du menu pour les utilisateurs qui n'ont pas le rôle correct, parce que quand ils le voient et cliquez dessus et il leur dit qu'ils n'ont pas la permission, ils le voudront. S'ils ne savent pas que c'est là, c'est mieux pour tout le monde ...

Quelque chose comme ceci est en fin de compte l'objectif que je cherche à atteindre, mais je suis à la recherche de l'approche plus MVC aromatisée, où la "vue" est "stupide":

<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

Je suis ... je pense. Il y a deux niveaux d'utilisateur, Normal et Admin. Seul l'administrateur peut voir les listes Société et Utilisateur, les attributs [Autoriser] sur le contrôleur empêchent l'accès non autorisé, mais je veux cacher la vue aux non-administrateurs afin qu'ils n'obtiennent même pas l'idée que c'est là dans leur tête. – Nate

Répondre

15

Je l'ai fait quelque chose comme ceci:

  • utilisent une classe de base commune pour mes contrôleurs (« couche de super-type »)
  • dans le BaseController, passer outre OnActionExecuted (vous pouvez également définir un attribut ActionFilter pour cette)

Quelque chose comme ceci:

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

Dans la page principale:

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

(Note: en réalité, j'ai un MasterViewModel qui contient entre autres le modèle de menu)

+0

Je suppose que ActionExecutedContext aura des informations sur l'utilisateur actuel? et j'ai juste besoin de mettre à jour tous mes contrôleurs pour hériter de ce nouveau contrôleur de base que j'ai défini? – Nate

+1

Oui, ActionExecutedContext vous donne accès à a.o. le HttpContext – jeroenh

+2

@jeroenh: Qu'est-ce qu'un a.o. ? – Pretzel

2

Avez-vous entendu parler de MvcContrib « s MenuBuilder?

Sinon, je vous suggère de jeter un coup d'œil. L'exemple de projet UI est un bon moyen de commencer à apprendre à l'utiliser.

0

Comme @SD » dit, vous pouvez créer une « aide brillante » qui avec soit rendre le lien, ou non, en fonction de vos exigences de sécurité.

Voici une bonne lecture sur des aides personnalisées (vers le bas):

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

1

Habituellement je vérifie simplement le rôle d'une manière similaire que vous avez fait et soit rendu une vue partielle avec les liens ou il suffit de les créer. Quelque chose comme ceci utilisant la syntaxe de Razor. J'utilise T4MVC pour les actions.

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

Pour plus de sécurité, j'utiliser la sécurité Fluent. J'espère que cela aide.

2

Personne n'a mentionné MvcSiteMapProvider qui le fait et peut être facilement intégré dans votre projet Visual Studio en utilisant NuGet.

0

La solution de Joe était de loin la plus simple et a fonctionné pour moi. J'ai des pages présentes dans des zones séparées pour lesquelles j'ai besoin de configurer rapidement un système de menu qui réagit et fonctionne en fonction de la zone dans laquelle l'utilisateur est présent.Aussi dans mon cas il n'y a pas de liens inter-zone dans mon système, donc je vais à configure multiple sitemaps for the MvcSiteMapProvider suivant.

J'espère que cela aidera tous ceux qui cherchent une solution simple et efficace!

Questions connexes