web-dev-qa-db-fra.com

Comment lire les attributs de la méthode d'action dans ASP.NET Core MVC?

Basé sur cet article J'essaie de créer une implémentation IActionFilter pour ASP.NET Core qui peut traiter les attributs marqués sur le contrôleur et l'action du contrôleur. Bien que la lecture des attributs du contrôleur soit facile, je n'arrive pas à trouver un moyen de lire les attributs définis sur la méthode d'action.

Voici le code que j'ai en ce moment:

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

Ma question est: comment lire les attributs de la méthode d'action dans ASP.NET Core MVC?

46
Steven

Vous pouvez accéder au MethodInfo de l'action via la classe ControllerActionDescriptor :

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

La classe MVC 5 ActionDescriptor utilisée pour implémenter l'interface ICustomAttributeProvider qui donnait accès aux attributs. Pour une raison quelconque, cela a été supprimé dans la classe ASP.NET Core MVC ActionDescriptor .

57
Henk Mollema

J'ai créé une méthode d'extension qui imite le GetCustomAttributes original basé sur la solution de 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>();
    }

J'espère que ça aide.

6
Axel Márquez

Mon attribut personnalisé est hérité d'ActionFilterAttribute. Je l'ai mis sur mon contrôleur mais il y a une action qui n'en a pas besoin. Je veux utiliser l'attribut AllowAnonymous pour ignorer cela mais cela ne fonctionne pas. J'ajoute donc cet extrait dans mon attribut personnalisé pour trouver le AllowAnonymous et le sauter. Vous pouvez en obtenir d'autres dans la boucle 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;
                }
            }
        }
    }
5
MichaelMao

Comme répondu par Henk Mollena

public void OnActionExecuting(ActionExecutingContext context) { var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; if (controllerActionDescriptor != null) { var controllerAttributes = controllerActionDescriptor .MethodInfo .GetCustomAttributes(inherit: true); } }

est la bonne façon de vérifier la présence d'un attribut appliqué à une action .

Je veux juste ajouter à sa réponse au cas où si vous voulez vérifier la présence d'un attribut appliqué au contrôleur

public void OnActionExecuting(ActionExecutingContext context)
{
    var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
    if (controllerActionDescriptor != null)
    {
        var actionAttributes = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(inherit: true);
    }
}

Vous pouvez également utiliser la fonction surchargée des fonctions GetCustomAttributes pour obtenir vos attributs spécifiques

var specificAttribute = GetCustomAttributes(typeof(YourSpecificAttribute), true).FirstOrDefault()

0
Saurabh Pati