2009-12-07 34 views
7

Estoy tratando de descubrir cómo mostrar/ocultar enlaces para los usuarios en función de sus roles. Sé cómo configurar el atributo authorize para un método de acción, pero tengo problemas para hacer que los enlaces se muestren ocultos en una vista si el usuario es, por ejemplo, un administrador o un administrador en mi base de datos de roles.Mostrar/Ocultar enlaces en una vista ASP.Net MVC

¿Algún artículo o ejemplo de código bueno que alguien pueda señalarme?

Respuesta

11

En su vista puede hacer referencia al usuario IPrincipal a través de System.Web.Mvc.ViewPage 's User propiedad.

E.g. En su opinión, se puede tener algo como:

<% if (User.IsInRole("Admin")) { %> 
    <%= Html.ActionLink("Admin only link", "Edit", "Users") %> 
<% } %> 

<% if (User.IsInRole("Manager") || User.IsInRole("Admin")) { %> 
    <%= Html.ActionLink("Manager & Admin only link", "Edit", "Product") %> 
<% } %> 

HTHS,
Charles

+0

Gracias! Aquí hay un giro: tengo mis enlaces de pestaña en la página maestra y quiero que aparezca una pestaña para ciertos roles. ¿Sabes cómo puedo agregar una referencia a mi maestro para el IPrincipal? – Ben

+2

Usa 'HttpContext.Current.user' o' ViewContext.HttpContext.User' - eso debería ser el truco :-) – Charlino

+0

Ahh, ahora puedo seguir con las cosas ... ¡Agradezco la ayuda! – Ben

2

Esto es una cosa que realmente no me gusta con MVC (como en ASP.Net MVC, no el patrón) se encuentra una tendancey al movimiento de la lógica de UI en el marcado.

No hay forma de ejecutar pruebas unitarias en esa lógica una vez que está en el aspx.

Personly creo que los formularios web con un patrón de IU adecuado (MVC o MVP, etc.) serían más adecuados que tener la página llena de lógica condicional que no se puede probar.

+1

Como todavía me considero un principiante, me estoy poniendo cada vez mejor y estoy completamente de acuerdo con lo que dice y he llenado las páginas de marcado. Trabajo en webforms en mi trabajo diario y MVC en mis proyectos independientes y tengo muchos dolores de cabeza conflictivos al aprender ambos al mismo tiempo. Aunque no he aprendido mucho sobre la prueba unitaria, sin duda lo necesitaré algún día en el futuro cercano; y espero que para entonces el equipo de MVC se haya ocupado de esto. Gracias por el comentario +1 -ben – Ben

+2

Use Selenium para pruebas de UI. Puede ejecutar pruebas utilizando diferentes roles y luego probar la existencia de controles HTML (hey que rima). – Bob

1
<% if(HttpContext.Current.User.IsInRole("Admin")){%> <a href="/Admin">Admin</a> <% } %> 

Utilice este código. Esto es más fácil.

0

Utilizo una clase estática para la validación de roles y en el cshtml utilicé esta clase, la validación de roles está fuera de cshtml.

Tengo mis funciones autorizadas o contenido en la base de datos (por usuario o por función) por lo que no tiene que volver a implementar si la definición de acceso cambia.

public static class AuthorizeContent 
{ 
    public static bool AuthorizeAccessContent(string Content) 
    { 
     bool bReturn = false; 
     DBContext db = new DBContext(); 
     string[] RolesUser = Roles.GetRolesForUser(WebSecurity.CurrentUserName); 

     foreach (AuthorizedContentRole aut in db.AuthorizedContentRole) 
     { 
      foreach (string rol in RolesUser) 
      { 
       if (aut.Role==rol && aut.Content==Content) 
       { 
        bReturn = true; 
        break; 
       } 
      } 
     } 
     foreach (AuthorizedContentUser aut in db.AuthorizedContentUser) 
     { 
      if (aut.UserName == WebSecurity.CurrentUserName && aut.Content == Content) 
      { 
       bReturn = true; 
       break; 
      } 
     } 

     return bReturn; 
    } 

/// en el cshtml

@if (AuthorizeContent.AuthorizeAccessContent(Content)) 
{ 

    <li class="two"> 
     <h5>Administrator link</h5> 
     @Html.ActionLink("Admin secret info","Index", "Information") 
    </li> 
} 

también se podría utilizar como un filtro [AccionAuthorize (Acción = "Mi contenido")]

public class AccionAuthorizeAttribute : AuthorizeAttribute 
{ 
    public string Action { get; set; } 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (!filterContext.HttpContext.User.Identity.IsAuthenticated) 
      filterContext.Result = new HttpUnauthorizedResult(); 
     else if (!AutorizacionContenido.AutorizaAccesoContenido(Action)) 
      filterContext.Result = new HttpUnauthorizedResult(); 
     base.OnAuthorization(filterContext); 
    } 
} 
Cuestiones relacionadas