2012-09-30 10 views
8

Dopo aver letto il post "How to check if method has an attribute" sono un passo per risolvere un problema che mi tiene sveglio.Come verificare se il metodo ha un attributo (con interfacce, casting e abstract)

presento la situazione:

(sto lavorando con ASP.Net MVC 4)

Queste interfacce:

public interface IFlyable 
{ 
    ActionResult Fly(); 
}  

public interface IRunnable 
{ 
    ActionResult Run(); 
} 

Questa classe astratta:

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

Questo controller:

public class SuperManController : SuperHero,IFlyable,IRunnable { 

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

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

} 

Questa classe astratta (per le prove)

[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); 
     } 

    } 
} 

E infine questa classe ereditata da SuperHeroTest per testare SuperManController:

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

    private SuperManController _superManController; 

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


    protected override SuperManController GetSuperHero() 
    { 
     return _superManController; 
    } 

} 

Metodo MethodHasAuthorizeAttribute è: (dal post precedente)

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(); 
} 

Il mio problema è:

La chiamata MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly()) in SuperHeroTest classe cambio false quando deve restituire true.

(Il metodo implementato Fly nella classe SuperManController ha l'attributo Authorize).

Ho aggiunto l'attributo Authorize nel metodo Fly a IFlyable e quindi restituisce true.

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

Come posso fare per rendere MethodHasAuthorizeAttribute ispezionare l'attuazione piuttosto che l'interfaccia?

+0

Grazie Dove per la modifica! –

risposta

9

Con alcune modifiche al metodo IfSuperHeroCanFlyMustHaveAuthorizeAttribute() è possibile farlo funzionare.

Prima verifica se il controllore implementa l'interfaccia IFlyable. In tal caso, ottenere MethodInfo per il metodo Fly del controller. Quindi è sufficiente controllare gli attributi per il MethodInfo restituito. In questo modo stai controllando se l'implementazione ha l'attributo al posto dell'interfaccia.

i seguenti lavori: 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

Funziona perfettamente! Christophe grazie mille! –

+0

Il test passa se superHero non è IFlyable l'asserzione dovrebbe essere al di fuori del blocco if – Grokodile

Problemi correlati