How to read action method's attributes in ASP.NET Core MVC?

Steven picture Steven · Aug 7, 2015 · Viewed 27.5k times · Source

Based on this article I'm trying to create an IActionFilter implementation for ASP.NET Core that can process attributes that are marked on the controller and the controller's action. Although reading the controller's attributes is easy, I'm unable to find a way to read the attributes defined on the action method.

Here's the code I have right now:

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();
    }
}

My question is: how do I read the action method's attributes in ASP.NET Core MVC?

Answer

Henk Mollema picture Henk Mollema · Aug 7, 2015

You can access the MethodInfo of the action through the ControllerActionDescriptor class:

public void OnActionExecuting(ActionExecutingContext context)
{
    if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
    {
        var actionAttributes = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true);
    }
}

The MVC 5 ActionDescriptor class used to implement the ICustomAttributeProvider interface which gave access to the attributes. For some reason this was removed in the ASP.NET Core MVC ActionDescriptor class.