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.
Réponses
Trop de publicités?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);
}
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".
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"})]
- Réponses précédentes
- Plus de réponses
1 votes
Pourquoi ne pas créer une autre action et décorer les 5% avec celle-ci. Quelque chose comme NHibernateNotRequiredAttribute() ?
0 votes
weblogs.asp.net/imranbaloch/