如何检查方法有一个属性 [英] How to check if method has an attribute

查看:107
本文介绍了如何检查方法有一个属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个示例类

public class MyClass{

    ActionResult Method1(){
        ....
    } 

    [Authorize]
    ActionResult Method2(){
       ....
    }

    [Authorize]    
    ActionResult Method3(int value){
       ....
    }

}

现在我想要的是编写可以这样执行的函数返回真/假

Now what I want is to write a function returning true/false that can be executed like this

var controller = new MyClass();

Assert.IsFalse(MethodHasAuthorizeAttribute(controller.Method1));
Assert.IsTrue(MethodHasAuthorizeAttribute(controller.Method2));
Assert.IsTrue(MethodHasAuthorizeAttribute(controller.Method3));

我到这种地步。

public bool MethodHasAuthorizeAttribute(Func<int, ActionResult> function)
{
    return function.Method.GetCustomAttributes(typeof(AuthorizeAttribute), false).Length > 0;
}

将工作Method3。现在我该怎么做通用的方式,它会采取字符串和类作为参数呢?

would work for Method3. Now how can I do that generic in a way that it'll take strings and classes as parameters as well ?

推荐答案

与code的问题是公共BOOL MethodHasAuthorizeAttribute的签名(Func键&LT; INT,ActionResult的&GT;功能) MethodHasAuthorizeAttribute 只能匹配您指定的委托的签名参数一起使用。在这种情况下,方法返回一个的ActionResult 类型的参数 INT

The issue with your code is the signature of public bool MethodHasAuthorizeAttribute(Func<int, ActionResult> function). MethodHasAuthorizeAttribute can only be used with arguments matching the signature of the delegate you specified. In this case a method returning an ActionResult with a parameter of type int.

当你调用像这个方法MethodHasAuthorizeAttribute(controller.Method3),编译器会做一个方法组转换。这可能并不总是不理想,可以产生意想不到的结果(方法组转换并不总是straigthforward)。如果你试图调用 MethodHasAuthorizeAttribute(controller.Method1),你会得到一个编译错误,因为没有转换。

When you call this method like MethodHasAuthorizeAttribute(controller.Method3), the Compiler will do a method group conversion. This might not always be desired and can yield unexpected results (Method group conversions aren't always straigthforward). If you try to call MethodHasAuthorizeAttribute(controller.Method1) you will get a compiler error because there's no conversion.

一个更通用的解决方案可以与前pression树和著名的推法绝招来构建。它采用编译器生成的前pression树找到调用目标:

A more general solution can be constructed with expression trees and the famous "MethodOf" trick. It employs compiler generated expression trees to find the invocation target:

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

可以使用像这样的,但它也可以与任何方法中使用

You can use it like this, but it can also be used with any method:

MethodInfo method = MethodOf( () => controller.Method3( default( int ) ) );

有了这样的方式,我们可以构建一个通用的实现:

With that out of the way, we can build a general implementation:

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

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

好吧,多数民众赞成的方法。现在,如果你想申请的类或字段属性检查(因为它们实际上是方法,我就饶属性),我们需要在的MemberInfo 履行我们的检查,这是键入字段信息的MethodInfo 继承根。这一样容易提取属性搜索到一个单独的方法,并提供与漂亮的名字适当的转接方式:

Okay, thats for methods. Now, if you want to apply the Attribute check on classes or fields to (I'll spare properties because they are actually methods), we need to perform our check on MemberInfo, which is the inheritance root for Type, FieldInfo and MethodInfo. This as easy as extracting the Attribute search into a separate method and providing appropriate adapter methods with nice names:

public static bool MethodHasAuthorizeAttribute( Expression<System.Action> expression )
{
    MemberInfo member = MethodOf( expression );
    return MemberHasAuthorizeAttribute( member );
}

public static bool TypeHasAuthorizeAttribute( Type t)
{
    return MemberHasAuthorizeAttribute( t );
}

private static bool MemberHasAuthorizeAttribute( MemberInfo member )
{
    const bool includeInherited = false;
    return member.GetCustomAttributes( typeof( AuthorizeAttribute ), includeInherited ).Any();
}

我要离开领域实现作为一个练习,您可以使用同样的伎俩推法。

I'll leave the implementation for fields as an exercise, you can employ the same trick as MethodOf.

这篇关于如何检查方法有一个属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆