9

投稿「メソッドに属性があるかどうかを確認する方法」を読んだ後、私は目を覚まし続ける問題を解決するための一歩です。

私は状況を提示します:

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

    }
}

最後に、このクラスはSuperHeroTesttestから継承されます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())は、返すべきときに返されます。SuperHeroTestfalsetrue

Fly(クラスで実装されたメソッドにSuperManControllerは属性がありますAuthorize)。

AuthorizeメソッドFlyに属性を追加してIFlyableから、 を返しますtrue

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

MethodHasAuthorizeAttributeインターフェイスではなく実装を検査するにはどうすればよいですか?

4

1 に答える 1

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();
    }
}
于 2012-09-30T09:20:26.093 に答える