Проблема с вашим кодом - подпись 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.