如何检查方法是否具有属性(带接口,强制转换和抽象)

时间:2012-09-30 05:40:39

标签: c# asp.net-mvc unit-testing reflection custom-attributes

阅读帖子“How to check if method has an attribute”后,我是解决让我保持清醒的问题的一步。

我介绍情况:

(我正在使用ASP.Net MVC 4)

这些界面

public interface IFlyable
{
    ActionResult Fly();
}    

public interface IRunnable
{
    ActionResult Run();
}

此抽象类

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

此控制器:

public class SuperManController : SuperHero,IFlyable,IRunnable {

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

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

}

此抽象类(用于测试)

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

    }
}

最后这个类继承自SuperHeroTest以测试SuperManController

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

    private SuperManController _superManController;

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


    protected override SuperManController GetSuperHero()
    {
        return _superManController;
    }

}

方法MethodHasAuthorizeAttribute是:(来自上面的帖子)

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

我的问题是:

MethodHasAuthorizeAttribute(() => superHeroFlyable.Fly())课程中的SuperHeroTest来电{}返回false时应该返回true

(班级Fly中实施的方法SuperManController具有属性Authorize)。

我将方法Authorize中的属性Fly添加到IFlyable,然后返回true

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

如何让MethodHasAuthorizeAttribute检查实现而不是界面?

1 个答案:

答案 0 :(得分:9)

通过对IfSuperHeroCanFlyMustHaveAuthorizeAttribute()方法的一些修改,您可以使其工作。

首先检查控制器是否实现了IFlyable接口。如果是这样,请获取控制器的Fly方法的MethodInfo。然后,您只需要检查返回的MethodInfo的属性。这样您就可以检查实现是否具有属性而不是接口。

以下工作正常:

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