2010-08-25 9 views
10

Estrarre il codice di esempio da http://lukesampson.com/post/471548689/entering-and-exiting-https-with-asp-net-mvc scritto per ASP.NET MVC2, ho notato che è possibile verificare se un attributo personalizzato viene applicato all'azione o al controller corrente da Accedendo filterContext.ActionDescriptor e filterContext.ActionDescriptor.ControllerDescriptor rispettivamente:Ottieni un elenco di attributi personalizzati per l'azione/controller corrente in 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 
    } 
} 

Quale sarebbe il metodo di ASP.NET MVC 1 di controllare l'azione e controller per un attributo personalizzato? In ASP.NET MVC 1 non è disponibile lo filterContext.ActionDescriptor.

risposta

6

Questo sembra funzionare ... c'è un modo migliore/più corretto in 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

ho bisogno di sapere - che cosa questi rendimenti fanno? Perché stai solo tornando? – muttley91

+0

Puoi vedere nel codice originale nella domanda che questo frammento si trova all'interno del metodo "public void OnAuthorization" di un attributo. Se RequireHttpsAttribute si trova sul controller o sull'azione corrente, la cosa migliore da fare è il "ritorno" fuori dal metodo e continuare come se nulla fosse successo. Ma se RequireHttps NON è sul controller o azione allora eseguirà del codice, in questo caso probabilmente reindirizzando il browser su un protocollo non HTTPS. – DavGarcia

+0

Si noti che questo snippet era per ASP.NET MVC 1 e forse MVC 2. Poiché MVC 3, ci sono stati modi migliori per affrontare il problema del controllo dell'esistenza di controller e filtri di azione, come indicato da Sunday Ironfoot. – DavGarcia

18

ancora migliore e più affidabile * approccio:

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

Anche se questo potrebbe essere MVC 3.0 + solo.

+3

Questo non sembra fare la stessa cosa. Ho provato questo con un attributo sul controller e questo ha restituito false. Usare il codice della domanda originale funziona comunque bene. –

+0

Utilizzando due insieme funzionano molto bene in MVC 4 'if (filterContext.Controller.GetType() GetCustomAttributes (typeof (SkipLocationFilterAttribute), true) .Any()). \t \t \t \t { \t \t \t \t \t di ritorno; \t \t \t \t} \t \t \t \t se (filterContext.ActionDescriptor.GetCustomAttributes (typeof (SkipLocationFilterAttribute), false) .Any()) \t \t \t \t { \t \t \t \t \t di ritorno; \t \t \t \t} ' – PvtVandals

+0

@PvtVandals Ero in cerca di un posto dove mettere un'edizione laminata oro dei tuoi (ho derivato in modo indipendente), [Tada] (http://stackoverflow.com/a/34956930/11635) –

11

edizione Goldplated, lavora su MVC5, probabilmente 4/3:

filterContext.HasMarkerAttribute<RequireHttpsAttribute>() 

usa questo set di estensioni helper:

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

Grazie per postare questo! – agrath

+0

Per chi legge questo, è possibile modificare 'AuthorizationContext' in' ActionExecutingContext' per rendere questi metodi di estensione funzionanti con regolare 'ActionFilterAttribute's – elexis

+1

@elexis Buon punto, grazie !; modificato in –

Problemi correlati