80 votes

Comment désactiver sélectivement un filtre global dans ASP.Net MVC ?

J'ai mis en place un filtre global pour toutes les actions de mon contrôleur dans lesquelles j'ouvre et ferme des sessions NHibernate. 95% de ces actions ont besoin d'un accès à la base de données, mais 5% n'en ont pas besoin. Existe-t-il un moyen simple de désactiver ce filtre global pour ces 5%. Je pourrais faire l'inverse et ne décorer que les actions qui ont besoin de la base de données, mais cela représenterait beaucoup plus de travail.

1 votes

Pourquoi ne pas créer une autre action et décorer les 5% avec celle-ci. Quelque chose comme NHibernateNotRequiredAttribute() ?

0 votes

158voto

Darin Dimitrov Points 528142

Vous pourriez écrire un attribut de marqueur :

public class SkipMyGlobalActionFilterAttribute : Attribute
{
}

puis, dans votre filtre d'action globale, vérifiez la présence de ce marqueur sur l'action :

public class MyGlobalActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(SkipMyGlobalActionFilterAttribute), false).Any())
        {
            return;
        }

        // here do whatever you were intending to do
    }
}

et si vous souhaitez exclure une action du filtre global, il vous suffit de la décorer avec l'attribut marker :

[SkipMyGlobalActionFilter]
public ActionResult Index()
{
    return View();
}

0 votes

Une très bonne solution. Je me demande comment je n'y ai pas pensé tout seul. Je vous remercie.

5 votes

Merci pour votre aide. Juste pour aider les futurs utilisateurs, vous pouvez également mettre la même chose sur un contrôleur, et utiliser filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes pour l'appliquer à toutes les actions.

4 votes

Si vous avez suivi la solution api, la syntaxe est légèrement différente : actionContext.ActionDescriptor.GetCustomAttributes<SkipMyGlobalActionFilter>().Any()

16voto

Dr. MAF Points 864

Bien que la réponse acceptée par Darin Dimitrov soit correcte et fonctionne bien, la réponse la plus simple et la plus efficace que j'ai trouvée est la suivante aquí .

Il vous suffit d'ajouter une propriété booléenne à votre attribut et de la vérifier, juste avant que votre logique ne commence :

public class DataAccessAttribute: ActionFilterAttribute
{
    public bool Disable { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (Disable) return;

        // Your original logic for your 95% actions goes here.
    }
}

Ensuite, lors de vos actions à 5 %, utilisez-le comme suit :

[DataAccessAttribute(Disable=true)]
public ActionResult Index()
{            
    return View();
}

1 votes

J'ai remarqué un petit problème : si vous spécifiez un ordre dans la déclaration globale du filtre, vous devez également spécifier le même ordre dans l'attribut. Par exemple [DataAccessAttribute(Disable=true,Order=2)] y filters.Add(new DataAccessAttribute(), 2);

8voto

g t Points 2660

Dans AspNetCore, la réponse acceptée par @darin-dimitrov peut être adaptée pour fonctionner comme suit :

Premièrement, mettre en œuvre IFilterMetadata sur l'attribut du marqueur :

public class SkipMyGlobalActionFilterAttribute : Attribute, IFilterMetadata
{
}

Recherchez ensuite dans la base de données Filters pour cet attribut sur la page ActionExecutingContext :

public class MyGlobalActionFilter : IActionFilter
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.Filters.OfType<SkipMyGlobalActionFilterAttribute>().Any())
        {
            return;
        }

        // etc
    }
}

6voto

Leniel Macaferi Points 38324

Vous pouvez aussi faire ce qui est décrit dans cet excellent article :

Exclure un filtre

Il suffit d'implémenter un ExcludeFilterAttribute et ensuite un ExcludeFilterProvider .

Une solution propre et qui a très bien fonctionné pour moi !

4voto

Markus Wagner Points 459

Du moins aujourd'hui, c'est assez facile : pour exclure tous les filtres d'une action, il suffit d'ajouter l'attribut Attribut OverrideActionFiltersAttribute .

Il existe des attributs similaires pour d'autres filtres : Attribut OverrideAuthentication , Attribut OverrideAuthorization y Attribut OverrideException .

Voir aussi https://www.strathweb.com/2013/06/overriding-filters-in-asp-net-web-api-vnext/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X