2010-02-04 53 views
15

He visto algunas preguntas similares, pero ninguna que se parece a lo que estoy tratando de hacer.Construyendo un menú de página maestra ASP.NET MVC dinámicamente, basado en el "Rol" del usuario actual

Ésta es mi actual aplicación w/a ningún tipo de seguridad:

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

Esto está muy bien, y las obras anteriores. Tengo [Autorizar] Configuración de atributos en las Acciones para CController y DController para evitar el acceso no autorizado, pero me gustaría eliminar esos elementos del menú para los usuarios que no tienen el Rol correcto, porque cuando lo ven y hacen clic en él y les dice que no tienen permiso, lo querrán. Si ellos no saben que está ahí, eso es mejor para todos los involucrados ...

Algo como esto es en última instancia el objetivo que trato de alcanzar, pero estoy buscando el enfoque MVC con más sabores, donde la "vista" es "tonto":

<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

Yo soy ... Creo. Hay dos niveles de usuario, Normal y Admin. Solo el administrador puede ver las listas de empresas y usuarios, los atributos [Autorizar] en el controlador evitan el acceso no autorizado, pero quiero ocultar la vista de los que no son de administrador para que ni siquiera se den cuenta de que está ahí en su cabeza. – Nate

Respuesta

15

he hecho algo como esto:

  • utilizar una clase base común para mis controladores ('capa de supertipo')
  • en el BaseController, anular OnActionExecuted (también se puede definir un atributo ActionFilter para este)

Algo como esto:

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

En la página maestra:

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

(Nota: en realidad, tengo un MasterViewModel que contiene entre otros el modelo de menú)

+0

Supongo que ActionExecutedContext tendrá información sobre el usuario actual? y simplemente necesito actualizar todos mis controladores para heredar de este nuevo controlador base que he definido? – Nate

+1

sí, ActionExecutedContext le da acceso a a.o. el HttpContext – jeroenh

+2

@jeroenh: ¿Qué es a.o. ? – Pretzel

2

se entero de MvcContrib 's MenuBuilder?

Si no, le sugiero que lo revise. El proyecto de ejemplo UI es una buena forma de comenzar a aprender a usarlo.

0

Como @SD", dijo, puede crear un 'ayudante brillante' que cualquiera de los dos procesa el enlace, o no, en función de sus requisitos de seguridad.

Aquí es una buena lectura de ayudantes personalizados (hacia abajo):

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

1

Por lo general simplemente marque el papel de una manera similar que hizo y entonces o bien rinden una vista parcial con la relación o solo créelos. Algo así usando la sintaxis de Razor. Yo uso T4MVC para acciones.

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

Para seguridad utilizo Fluent Security. Espero que esto ayude.

2

Nadie mencionó MvcSiteMapProvider que hace esto y se puede integrar fácilmente en su proyecto de Visual Studio usando NuGet.

0

La solución de Joe fue de lejos la más simple y funcionó para mí. Tengo páginas presentes en áreas separadas para las que necesito configurar rápidamente un sistema de menú que reaccione y funcione según la zona en la que esté presente el usuario.También en mi caso no hay enlaces de áreas cruzadas en mi sistema, así que voy al próximo configure multiple sitemaps for the MvcSiteMapProvider.

¡Espero que esto ayude a cualquier persona que busque una solución simple y efectiva!

Cuestiones relacionadas