After reading the post "How to check if method has an attribute" I'm one step to solve a problem that keeps me awake.
( I'm working with ASP.Net MVC 4 )
These interfaces:
public interface IFlyable
{
ActionResult Fly();
}
public interface IRunnable
{
ActionResult Run();
}
This abstract class :
public abstract class SuperHero : Controller
{
public void SavePeople()
{
}
}
This controller :
public class SuperManController : SuperHero,IFlyable,IRunnable {
[Authorize]
public ActionResult Fly(){
// Flying...
}
[Authorize]
public ActionResult Run(){
// Running...
}
}
This abstract class ( for tests )
[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);
}
}
}
And finally this class inherited from SuperHeroTest
to test SuperManController
:
[TestClass]
public class SuperManControllerTest : SuperHeroTest<SuperManController>{
private SuperManController _superManController;
public SuperManControllerTest(){
_superManController=new SuperManController();
}
protected override SuperManController GetSuperHero()
{
return _superManController;
}
}
Method MethodHasAuthorizeAttribute
is : (from the post above)
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();
}
The call MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly())
in SuperHeroTest
class return false
when it should return true
.
(The implemented method Fly
in class SuperManController
has the attribute Authorize
).
I added the attribute Authorize
in method Fly
into IFlyable
and then returns true
.
public interface IFlyable
{
[Authorize]
ActionResult Fly();
}
How I can do to make MethodHasAuthorizeAttribute
inspect the implementation rather than the interface?
With some modifications to the IfSuperHeroCanFlyMustHaveAuthorizeAttribute() method you can get it to work.
First check if you controller implements the IFlyable interface. If so, get the MethodInfo for the controller's Fly method. Then you only need to check the attributes for the returned MethodInfo. This way you are checking if the implementation has the attribute instead of the interface.
The following works 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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With