Как читать атрибуты метода действий в ASP.NET Core MVC?
Основываясь на этой статье Я пытаюсь создать реализацию IActionFilter
для ядра ASP.NET, которая может обрабатывать атрибуты, помеченные на контроллер и действие контроллера. Хотя чтение атрибутов контроллера легко, я не могу найти способ прочитать атрибуты, определенные в методе действий.
Вот код, который у меня есть прямо сейчас:
public sealed class ActionFilterDispatcher : IActionFilter
{
private readonly Func<Type, IEnumerable> container;
public ActionFilterDispatcher(Func<Type, IEnumerable> container)
{
this.container = container;
}
public void OnActionExecuting(ActionExecutingContext context)
{
var attributes = context.Controller.GetType().GetCustomAttributes(true);
attributes = attributes.Append(/* how to read attributes from action method? */);
foreach (var attribute in attributes)
{
Type filterType = typeof(IActionFilter<>).MakeGenericType(attribute.GetType());
IEnumerable filters = this.container.Invoke(filterType);
foreach (dynamic actionFilter in filters)
{
actionFilter.OnActionExecuting((dynamic)attribute, context);
}
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
throw new NotImplementedException();
}
}
Мой вопрос: как я могу прочитать атрибуты метода действия в ASP.NET Core MVC?
Ответы
Ответ 1
Вы можете получить доступ к MethodInfo
действия через класс ControllerActionDescriptor
:
public void OnActionExecuting(ActionExecutingContext context)
{
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
var actionAttributes = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true);
}
}
Класс MVC 5 ActionDescriptor
, используемый для реализации интерфейса ICustomAttributeProvider
, который дал доступ к атрибутам. По какой-то причине это было удалено в классе ASP.NET Core MVC ActionDescriptor
.
Ответ 2
Я создал метод расширения, который имитирует исходный GetCustomAttributes
, основанный на решении Henk Mollema.
public static IEnumerable<T> GetCustomAttributes<T>(this Microsoft.AspNet.Mvc.Abstractions.ActionDescriptor actionDescriptor) where T : Attribute
{
var controllerActionDescriptor = actionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
return controllerActionDescriptor.MethodInfo.GetCustomAttributes<T>();
}
return Enumerable.Empty<T>();
}
Надеюсь, что это поможет.
Ответ 3
Мой пользовательский атрибут наследуется от ActionFilterAttribute. Я надел его на контроллер, но одно действие ему не нужно. Я хочу использовать атрибут AllowAnonymous
, чтобы игнорировать это, но он не работает. Поэтому я добавляю этот фрагмент в свой собственный атрибут, чтобы найти AllowAnonymous
и пропустить его. Вы можете получить другие в цикле for.
public class PermissionAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
foreach (var filterDescriptors in context.ActionDescriptor.FilterDescriptors)
{
if (filterDescriptors.Filter.GetType() == typeof(AllowAnonymousFilter))
{
return;
}
}
}
}