Реализация WebApi iActionFilter.Как мне прочитать пользовательский атрибут контроллера? - PullRequest
0 голосов
/ 28 ноября 2018

Я реализую пользовательский фильтр аутентификации и использую подход «Пассивные атрибуты», описанный здесь: http://blog.ploeh.dk/2014/06/13/passive-attributes/

DI работает, как и ожидалось, но я не могу понять, как читать пользовательские атрибуты из самого контроллера?Я хотел бы, чтобы как отдельные действия, так и целые контроллеры поддерживали эту функцию.

Пример контроллера:

[TokenAuth] // This attribute not "visible"
public class SupportController : ApiController
{
    private ISecurityService SecurityService { get; }

    public SupportController(ISecurityService securityService)
    {
        this.SecurityService = securityService;
    }

    [TokenAuth] // This attribute works
    [HttpGet]
    public object StartupData()
    {
        return "Startup data";
    }
}

Это часть кода фильтра, где я читаю пользовательский атрибут:

public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
    var tokenAuthAttribute = actionContext.ActionDescriptor.GetCustomAttributes<TokenAuthAttribute>(true).SingleOrDefault();

    // This line below exists unless attribute placed on method/action

    if (tokenAuthAttribute == null) return continuation();

    var req = actionContext.Request;

Есть ли способ получить доступ к атрибутам контроллера?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Вот полный абстрактный класс с атрибутом в качестве универсального аргумента.Вы можете наследовать его, указав свой атрибут, а затем просто переопределить ExecuteFilterBehavior.Это проверит атрибут на контроллере и метод.Вы можете изменить его, чтобы сделать только один или другой.

public abstract class ActionFilterBehaviorBase<TAttribute> : IActionFilter where TAttribute : Attribute
{
    public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        if (ControllerHasAttribute(actionContext) || ActionHasAttribute(actionContext))
        {
            return ExecuteFilterBehavior(actionContext, cancellationToken, continuation);
        }
        return continuation();
    }

    protected abstract Task<HttpResponseMessage>  ExecuteFilterBehavior(HttpActionContext actionContext, CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation);

    public virtual bool AllowMultiple { get; } = false;

    private bool ControllerHasAttribute(HttpActionContext actionContext)
    {
        return actionContext
                .ControllerContext.Controller.GetType()
                .GetCustomAttributes(false)
                .Any(attribute => attribute.GetType().IsAssignableFrom(typeof(TAttribute)));
    }

    private bool ActionHasAttribute(HttpActionContext actionContext)
    {
        return actionContext
            .ActionDescriptor
            .GetCustomAttributes<TAttribute>()
            .Any();
    }
}

Более подробно здесь .

0 голосов
/ 28 ноября 2018

Дескриптор действия должен дать вам доступ к типу контроллера через свойство ControllerDescriptor

var actionDescriptor = actionContext.ActionDescriptor;

var tokenAuthAttribute = 
    actionDescriptor.GetCustomAttributes<TokenAuthAttribute>(true).SingleOrDefault() ??
    actionDescriptor.ControllerDescriptor.GetCustomAttributes<TokenAuthAttribute>(true).SingleOrDefault();

//...

. Выше сначала проверяется дескриптор действия, и если ничего не найдено, то проверяется дескриптор контроллера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...