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

2voto

Swapnil Points 1

Créer un fournisseur de filtre personnalisé. Écrire une classe qui implémentera IFilterProvider. Cette interface IFilterProvider possède une méthode GetFilters qui renvoie les filtres à exécuter.

public class MyFilterProvider : IFilterProvider
{
        private readonly List<Func<ControllerContext, object>> filterconditions = new List<Func<ControllerContext, object>>();
        public void Add(Func<ControllerContext, object> mycondition)
        {
            filterconditions.Add(mycondition);
        }

        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
        {
            return from filtercondition in filterconditions
                   select filtercondition(controllerContext) into ctrlContext
                   where ctrlContext!= null
                   select new Filter(ctrlContext, FilterScope.Global);
        }
}

\=============================================================================
Dans Global.asax.cs

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            MyFilterProvider provider = new MyFilterProvider();
            provider.Add(d => d.RouteData.Values["action"].ToString() != "SkipFilterAction1 " ? new NHibernateActionFilter() : null);
            FilterProviders.Providers.Add(provider);
        }

protected void Application_Start()
{
    RegisterGlobalFilters(GlobalFilters.Filters);
}

2voto

ashilon Points 465

Je pense avoir réussi à le faire fonctionner pour ASP.NET Core.
Voici le code :

public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // Prepare the audit
        _parameters = context.ActionArguments;

        await next();

        if (IsExcluded(context))
        {
            return;
        }

        var routeData = context.RouteData;

        var controllerName = (string)routeData.Values["controller"];
        var actionName = (string)routeData.Values["action"];

        // Log action data
        var auditEntry = new AuditEntry
        {
            ActionName = actionName,
            EntityType = controllerName,
            EntityID = GetEntityId(),
            PerformedAt = DateTime.Now,
            PersonID = context.HttpContext.Session.GetCurrentUser()?.PersonId.ToString()
        };

        _auditHandler.DbContext.Audits.Add(auditEntry);
        await _auditHandler.DbContext.SaveChangesAsync();
    }

    private bool IsExcluded(ActionContext context)
    {
        var controllerActionDescriptor = (Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor;

        return controllerActionDescriptor.ControllerTypeInfo.IsDefined(typeof(ExcludeFromAuditing), false) ||
               controllerActionDescriptor.MethodInfo.IsDefined(typeof(ExcludeFromAuditing), false);
    }

Le code correspondant se trouve dans la méthode "IsExcluded".

1voto

Nataly Points 101

Vous pouvez modifier le code de votre filtre comme suit :

 public class NHibernateActionFilter : ActionFilterAttribute
    {
        public IEnumerable<string> ActionsToSkip { get; set; }

        public NHibernateActionFilter(params string[] actionsToSkip)
        {
            ActionsToSkip = actionsToSkip;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (null != ActionsToSkip && ActionsToSkip.Any(a => 
String.Compare(a,  filterContext.ActionDescriptor.ActionName, true) == 0))
                {
                    return;
                }
           //here you code
        }
    }

Et l'utiliser :

[NHibernateActionFilter(new[] { "SkipFilterAction1 ", "Action2"})]

-1voto

Nariman Points 3484

La meilleure réponse à cette question est fournie dans une autre question :

MVC 3 GlobalFilters Exclude

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