Подтвердить что ты не робот

Как читать атрибуты метода действий в 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?

4b9b3361

Ответ 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;
                }
            }
        }
    }