2012-09-30 26 views
8

Después de leer el mensaje "How to check if method has an attribute" Estoy a un paso para resolver un problema que me mantiene despierto.Cómo comprobar si el método tiene un atributo (con interfaces, fundición y resumen)

presento la situación:

(Estoy trabajando con ASP.Net MVC 4)

Estas interfaces:

public interface IFlyable 
{ 
    ActionResult Fly(); 
}  

public interface IRunnable 
{ 
    ActionResult Run(); 
} 

Esta clase abstracta:

public abstract class SuperHero : Controller 
{ 
    public void SavePeople() 
    { 
    }  
} 

Este controlador:

public class SuperManController : SuperHero,IFlyable,IRunnable { 

    [Authorize] 
    public ActionResult Fly(){ 
     // Flying... 
    }  

    [Authorize] 
    public ActionResult Run(){ 
     // Running... 
    }  

} 

Esta clase abstracta (para pruebas)

[TestClass] 
public abstract class SuperHeroTest<TSuperHero>{ 

    protected abstract TSuperHero GetSuperHero(); 

    [TestMethod] 
    public void IfSuperHeroCanFlyMustHaveAuthorizeAttribute(){ 

     var superHero=GetSuperHero(); 

     if(superHero is IFlyable) 
     { 
      var superHeroFlyable = (IFlyable) superHero; 

      var have = MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly()); 

      Assert.IsTrue(have); 
     } 

    } 
} 

Y finalmente esta clase heredada de SuperHeroTest para probar SuperManController:

[TestClass] 
public class SuperManControllerTest : SuperHeroTest<SuperManController>{ 

    private SuperManController _superManController; 

    public SuperManControllerTest(){ 
     _superManController=new SuperManController(); 
    } 


    protected override SuperManController GetSuperHero() 
    { 
     return _superManController; 
    } 

} 

Método MethodHasAuthorizeAttribute es: (desde el post anterior)

public static MethodInfo MethodOf(Expression<System.Action> expression) 
{ 
    MethodCallExpression body = (MethodCallExpression)expression.Body; 
    return body.Method; 
} 

public static bool MethodHasAuthorizeAttribute(Expression<System.Action> expression) 
{ 
    var method = MethodOf(expression); 

    const bool includeInherited = false; 
    return method.GetCustomAttributes(typeof(AuthorizeAttribute),includeInherited).Any(); 
} 

Mi problema es:

La llamada MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly()) en SuperHeroTest y vuelta en clase false cuando debería devolver true.

(El método implementado Fly en la clase SuperManController tiene el atributo Authorize).

He añadido el atributo Authorize en el método Fly en IFlyable y luego devuelve true.

public interface IFlyable 
{ 
    [Authorize] 
    ActionResult Fly(); 
} 

¿Cómo puedo hacer para que inspeccione el MethodHasAuthorizeAttribute aplicación en lugar de la interfaz?

+0

Gracias Dove para la edición! –

Respuesta

9

Con algunas modificaciones al método IfSuperHeroCanFlyMustHaveAuthorizeAttribute() puede hacer que funcione.

Primero compruebe si su controlador implementa la interfaz IFlyable. De ser así, obtenga MethodInfo para el método Fly del controlador. Entonces solo necesita verificar los atributos para MethodInfo devuelto. De esta forma, está comprobando si la implementación tiene el atributo en lugar de la interfaz.

las siguientes obras: OK

[TestClass] 
public abstract class SuperHeroTest<TSuperHero> 
{ 
    protected abstract TSuperHero GetSuperHero(); 

    [TestMethod] 
    public void IfSuperHeroCanFlyMustHaveAuthorizeAttribute() 
    { 
     var superHero = GetSuperHero(); 

     if (superHero is IFlyable) 
     { 
      var superHeroFlyable = superHero; 
      var method = typeof (TSuperHero).GetMethod("Fly"); 
      var hasAttribute = 
       method.GetCustomAttributes(typeof (AuthorizeAttribute), false).Any(); 
      Assert.IsTrue(hasAttribute); 
     } 
    } 

    public static MethodInfo MethodOf(Expression<System.Action> expression) 
    { 
     var body = (MethodCallExpression)expression.Body; 
     return body.Method; 
    } 

    public static bool MethodHasAuthorizeAttribute(Expression<System.Action> expression) 
    { 
     var method = MethodOf(expression); 
     const bool includeInherited = false; 
     return method.GetCustomAttributes(
      typeof(AuthorizeAttribute), includeInherited).Any(); 
    } 
} 
+0

¡Funciona a la perfección! Christophe muchas gracias! –

+0

La prueba pasa si superHero no es IFlyable la afirmación debe estar fuera del bloque if – Grokodile

Cuestiones relacionadas