2010-08-25 15 views
10

Revisando el código de muestra de http://lukesampson.com/post/471548689/entering-and-exiting-https-with-asp-net-mvc escrito para ASP.NET MVC2, noté que pueden verificar si un atributo personalizado se aplica a la acción o controlador actual por acceder a filterContext.ActionDescriptor y filterContext.ActionDescriptor.ControllerDescriptor respectivamente:Obtener la lista de atributos personalizados para la acción/controlador actual en ASP.NET MVC

public class ExitHttpsIfNotRequiredAttribute : FilterAttribute, IAuthorizationFilter { 
    public void OnAuthorization(AuthorizationContext filterContext) { 
     // snip 

     // abort if a [RequireHttps] attribute is applied to controller or action 
     if(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return; 
     if(filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) return; 

     // snip 
    } 
} 

¿Cuál sería el método de ASP.NET MVC 1 de la comprobación de la acción y controlador para un atributo personalizado? En ASP.NET MVC 1 no hay filterContext.ActionDescriptor que pueda decir.

Respuesta

6

Esto parece funcionar ... ¿hay una forma mejor/más adecuada en ASP.NET MVC 1?

if (filterContext.Controller.GetType().GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) 
    return; 
string action = (string)filterContext.RouteData.Values["action"]; 
if (!string.IsNullOrEmpty(action) && filterContext.Controller.GetType().GetMethod(action).GetCustomAttributes(typeof(RequireHttpsAttribute), true).Length > 0) 
    return; 
+0

necesito saber - ¿qué hacen estas declaraciones? ¿Por qué estás volviendo? – muttley91

+0

Puede ver en el código original en la pregunta que este fragmento está dentro del método de "Autorización de anulación pública" de un atributo. Si RequireHttpsAttribute está en el controlador o acción actual, lo mejor que puede hacer es 'devolver' el método y continuar como si nada hubiera sucedido. Pero si RequireHttps NO está en el controlador ni en la acción, entonces ejecutará algún código, en este caso, probablemente redirija el navegador a un protocolo que no sea HTTPS. – DavGarcia

+0

Tenga en cuenta que este fragmento fue para ASP.NET MVC 1, y tal vez MVC 2. Desde MVC 3, ha habido mejores formas de lidiar con el problema de verificar la existencia de filtros de controlador y acción como señaló Sunday Ironfoot. – DavGarcia

18

aún mejor y más fiable * Enfoque:

filterContext.ActionDescriptor.GetCustomAttributes(
    typeof(RequireHttpsAttribute), true).Count> 0 

Aunque esto podría ser MVC 3.0 + solamente.

+3

Esto no parece hacer lo mismo. Intenté esto con un atributo en el controlador y esto devolvió falso. Sin embargo, usar el código de la pregunta original funciona bien. –

+0

Usando los dos juntos funcionan muy bien en MVC 4 'si (filterContext.Controller.GetType() GetCustomAttributes (typeof (SkipLocationFilterAttribute), true) .Cualquier()). \t \t \t \t { \t \t \t \t \t de retorno; \t \t \t \t} \t \t \t \t si (filterContext.ActionDescriptor.GetCustomAttributes (typeof (SkipLocationFilterAttribute), false) .Cualquier()) \t \t \t \t { \t \t \t \t \t de retorno; \t \t \t \t} ' – PvtVandals

+0

@PvtVandals que estaba buscando un lugar para poner una edición Goldplated de los suyos (I derivado de forma independiente), [tada] (http://stackoverflow.com/a/34956930/11635) –

11

edición enchapada en oro, trabaja en MVC5, probablemente 4/3:

filterContext.HasMarkerAttribute<RequireHttpsAttribute>() 

utiliza este conjunto de extensiones de ayuda:

public static class MarkerAttributeExtensions 
{ 
    public static bool HasMarkerAttribute<T>(this AuthorizationContext that) { 
     return that.Controller.HasMarkerAttribute<T>() 
      || that.ActionDescriptor.HasMarkerAttribute<T>(); 
    } 

    public static bool HasMarkerAttribute<T>(this ActionExecutingContext that) { 
     return that.Controller.HasMarkerAttribute<T>() 
      || that.ActionDescriptor.HasMarkerAttribute<T>(); 
    } 

    public static bool HasMarkerAttribute<T>(this ControllerBase that) { 
     return that.GetType().HasMarkerAttribute<T>(); 
    } 

    public static bool HasMarkerAttribute<T>(this Type that) { 
     return that.IsDefined(typeof(T), false); 
    } 

    public static IEnumerable<T> GetCustomAttributes<T>(this Type that) { 
     return that.GetCustomAttributes(typeof(T), false).Cast<T>(); 
    } 

    public static bool HasMarkerAttribute<T>(this ActionDescriptor that) { 
     return that.IsDefined(typeof(T), false); 
    } 

    public static IEnumerable<T> GetCustomAttributes<T>(this ActionDescriptor that) { 
     return that.GetCustomAttributes(typeof(T), false).Cast<T>(); 
    } 
} 
+1

Gracias por publicando esto! – agrath

+0

Para cualquiera que lea esto, puede cambiar 'AuthorizationContext' por' ActionExecutingContext' para hacer que estos métodos de extensión funcionen con 'ActionFilterAttribute's normal – elexis

+1

@elexis ¡Buen punto, gracias !; editado en. –

Cuestiones relacionadas