Ich habe einen globalen Filter für alle meine Controller-Aktionen eingerichtet, in denen ich NHibernate-Sitzungen öffne und schließe. 95% dieser Aktionen benötigen Datenbankzugriff, 5% jedoch nicht. Gibt es eine einfache Möglichkeit, diesen globalen Filter für diese 5% zu deaktivieren? Ich könnte umgekehrt vorgehen und nur die Aktionen dekorieren, die die Datenbank benötigen, aber das wäre weitaus mehr Arbeit.
76
Antworten:
Sie könnten ein Markerattribut schreiben:
public class SkipMyGlobalActionFilterAttribute : Attribute { }
und dann in Ihrem globalen Aktionsfilter auf das Vorhandensein dieses Markers in der Aktion testen:
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 } }
Wenn Sie dann eine Aktion aus dem globalen Filter ausschließen möchten, dekorieren Sie sie einfach mit dem Marker-Attribut:
[SkipMyGlobalActionFilter] public ActionResult Index() { return View(); }
quelle
Sie können auch das tun, was in diesem fantastischen Beitrag beschrieben wird:
Filter ausschließen
Implementieren Sie einfach eine benutzerdefinierte
ExcludeFilterAttribute
und dann eine benutzerdefinierteExcludeFilterProvider
.Saubere Lösung und hat super für mich funktioniert!
quelle
Die akzeptierte Antwort von Darin Dimitrov ist zwar in Ordnung und funktioniert gut, aber für mich ist die einfachste und effizienteste Antwort hier begründet .
Sie müssen Ihrem Attribut lediglich eine boolesche Eigenschaft hinzufügen und diese überprüfen, bevor Ihre Logik beginnt:
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. } }
Verwenden Sie es dann bei Ihren 5% -Aktionen einfach so:
[DataAccessAttribute(Disable=true)] public ActionResult Index() { return View(); }
quelle
[DataAccessAttribute(Disable=true,Order=2)]
undfilters.Add(new DataAccessAttribute(), 2);
In AspNetCore kann die akzeptierte Antwort von @ darin-dimitrov wie folgt angepasst werden:
Implementieren Sie zunächst
IFilterMetadata
das Markerattribut:public class SkipMyGlobalActionFilterAttribute : Attribute, IFilterMetadata { }
Suchen Sie dann in der
Filters
Eigenschaft nach diesem Attribut inActionExecutingContext
:public class MyGlobalActionFilter : IActionFilter { public override void OnActionExecuting(ActionExecutingContext context) { if (context.Filters.OfType<SkipMyGlobalActionFilterAttribute>().Any()) { return; } // etc } }
quelle
Erstellen Sie einen benutzerdefinierten Filteranbieter. Schreiben Sie eine Klasse, die IFilterProvider implementiert. Diese IFilterProvider-Schnittstelle verfügt über eine Methode GetFilters, die Filter zurückgibt, die ausgeführt werden müssen.
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); } }
================================================== ===========================
In 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); }
quelle
Nun, ich glaube, ich habe es für ASP.NET Core zum Laufen gebracht.
Hier ist der 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); }
Der relevante Code befindet sich in der Methode 'IsExcluded'.
quelle
Zumindest heutzutage ist dies recht einfach: Um alle Aktionsfilter von einer Aktion auszuschließen, fügen Sie einfach das OverrideActionFiltersAttribute hinzu .
Für andere Filter gibt es ähnliche Attribute: OverrideAuthenticationAttribute , OverrideAuthorizationAttribute und OverrideExceptionAttribute .
Siehe auch https://www.strathweb.com/2013/06/overriding-filters-in-asp-net-web-api-vnext/
quelle
Sie können Ihren Filtercode folgendermaßen ändern:
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 } }
Und benutze es:
[NHibernateActionFilter(new[] { "SkipFilterAction1 ", "Action2"})]
quelle