2010-08-25 3 views
10

En cochant l'exemple de code de http://lukesampson.com/post/471548689/entering-and-exiting-https-with-asp-net-mvc écrit pour ASP.NET MVC2, j'ai remarqué qu'ils peuvent vérifier si un attribut personnalisé est appliqué à l'action ou au contrôleur en cours par accès filterContext.ActionDescriptor et filterContext.ActionDescriptor.ControllerDescriptor respectivement:Obtenir la liste des attributs personnalisés pour l'action/contrôleur en cours dans 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 
    } 
} 

Quelle serait la méthode ASP.NET MVC 1 de vérifier l'action et contrôleur pour un attribut personnalisé? Dans ASP.NET MVC 1, il n'y a pas filterContext.ActionDescriptor que je peux dire.

Répondre

6

Cela semble fonctionner ... existe-t-il une meilleure/plus correcte façon dans 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

Je dois savoir - qu'est-ce que ces déclarations font? Pourquoi êtes-vous juste de retour? – muttley91

+0

Vous pouvez voir dans le code original de la question que cet extrait est dans la méthode "public void OnAuthorization" d'un attribut. Si le RequireHttpsAttribute est sur le contrôleur ou l'action en cours, alors la meilleure chose à faire est le 'return' hors de la méthode et continuer comme si de rien n'était. Mais si RequireHttps n'est PAS sur le contrôleur ou l'action, il exécutera du code, dans ce cas probablement redirigeant le navigateur vers un protocole non-HTTPS. – DavGarcia

+0

Notez que cet extrait était pour ASP.NET MVC 1, et peut-être MVC 2. Depuis MVC 3, il y a eu de meilleures façons de résoudre le problème de vérification de l'existence du contrôleur et des filtres d'action comme le soulignait Sunday Ironfoot. – DavGarcia

18

approche encore mieux et plus fiable *:

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

Bien que cela pourrait être MVC 3.0+ uniquement.

+3

Cela ne semble pas faire la même chose. J'ai essayé ceci avec un attribut sur le contrôleur et ceci a renvoyé faux. En utilisant le code de la question d'origine fonctionne bien cependant. –

+0

utilisant à la fois travailler ensemble très bien dans MVC 4 'si (filterContext.Controller.GetType() GetCustomAttributes (typeof (SkipLocationFilterAttribute), true) .Tout().) \t \t \t \t { \t \t \t \t \t retour; \t \t \t \t} \t \t \t \t si (filterContext.ActionDescriptor.GetCustomAttributes (typeof (SkipLocationFilterAttribute), false) .Tout()) \t \t \t \t { \t \t \t \t \t retour; \t \t \t \t} ' – PvtVandals

+0

@PvtVandals que je cherchais un endroit pour mettre une édition goldplated de la vôtre (je tirais indépendamment), [Tada] (http://stackoverflow.com/a/34956930/11635) –

11

édition Goldplated, fonctionne sur MVC5, probablement 4/3:

filterContext.HasMarkerAttribute<RequireHttpsAttribute>() 

Utilise cet ensemble d'extensions d'aide:

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

Merci pour poster ceci! – agrath

+0

Pour quiconque lit ceci, vous pouvez changer 'AuthorizationContext' en' ActionExecutingContext' pour que ces méthodes d'extension fonctionnent avec les 'ActionFilterAttribute's habituels – elexis

+1

@elexis Bon point, merci !; édité en. –

Questions connexes