Проблема с вашим кодом - это подпись public bool MethodHasAuthorizeAttribute(Func<int, ActionResult> function)
. MethodHasAuthorizeAttribute
можно использовать только с аргументами, соответствующими подписи указанного делегата. В этом случае метод, возвращающий ActionResult
с параметром типа int
.
Когда вы вызываете этот метод как MethodHasAuthorizeAttribute(controller.Method3)
, компилятор выполняет преобразование группы методов. Это не всегда может быть желательным и может привести к неожиданным результатам (преобразования групп методов не всегда просты). Если вы попытаетесь вызвать MethodHasAuthorizeAttribute(controller.Method1)
, вы получите ошибку компилятора, потому что преобразования нет.
Более общее решение может быть построено с помощью деревьев выражений и известного трюка "MethodOf". Он использует сгенерированные компилятором деревья выражений для поиска цели вызова:
public static MethodInfo MethodOf( Expression<System.Action> expression )
{
MethodCallExpression body = (MethodCallExpression)expression.Body;
return body.Method;
}
Вы можете использовать его так, но его также можно использовать с любым методом:
MethodInfo method = MethodOf( () => controller.Method3( default( int ) ) );
Разобравшись с этим, мы можем построить общую реализацию:
public static bool MethodHasAuthorizeAttribute( Expression<System.Action> expression )
{
var method = MethodOf( expression );
const bool includeInherited = false;
return method.GetCustomAttributes( typeof( AuthorizeAttribute ), includeInherited ).Any();
}
Хорошо, это методы. Теперь, если вы хотите применить проверку атрибутов к классам или полям (я пощажу свойства, потому что они на самом деле являются методами), нам нужно выполнить нашу проверку на MemberInfo
, который является корнем наследования для Type
, FieldInfo
и MethodInfo
. Это так же просто, как выделить поиск по атрибутам в отдельный метод и предоставить соответствующие методы адаптера с красивыми именами:
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();
}
Я оставлю реализацию полей в качестве упражнения, вы можете использовать тот же трюк, что и MethodOf.
person
Johannes Rudolph
schedule
11.01.2012