2012-03-31 2 views
56

Я настроил глобальный фильтр для всех своих действий с контроллером, в которых я открываю и закрываю сеансы NHibernate. 95% этих действий требуют доступа к базе данных, но 5% - нет. Есть ли простой способ отключить этот глобальный фильтр для этих 5%. Я мог бы пойти наоборот и украсить только те действия, которые нужны для базы данных, но это будет гораздо больше работать.Как отключить глобальный фильтр в ASP.Net MVC выборочно

+1

насчет создания другого действия и украсить 5% с этим. Что-то вроде NHibernateNotRequiredAttribute()? – dreza

+0

https://weblogs.asp.net/imranbaloch/new-filter-overrides-in-asp-net-mvc-5-and-asp-net-web-api-2 – dovid

ответ

109

Вы могли бы написать атрибут маркера:

public class SkipMyGlobalActionFilterAttribute : Attribute 
{ 
} 

, а затем в вашем глобальном тесте действие фильтра на наличие этого маркера на действие:

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 
    } 
} 

, а затем, если вы хотите, чтобы исключить некоторые действия от глобального фильтра просто украшают его атрибутом маркера:

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

Действительно отличное решение. Интересно, как я сам не думал об этом. Благодарю. – zszep

+1

Хорошее простое решение. Благодаря! –

+0

Отличное решение. Вы экономите свое время. :) – Ankita

1

Вы можете изменить свой код фильтра, как это:

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 
     } 
    } 

И использовать:

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

Это один из способов сделать это, но немного сложно поддерживать с течением времени. – zszep

+1

Если вы измените свое имя действия и забыли изменить его в использовании атрибута, компилятор не предупредит вас. Вероятно, это может вызвать проблемы с обслуживанием. Я предпочитаю ответ Дарина, так как вам не нужно указывать действия вручную. – Nashenas

16

Вы также можете сделать то, что описано в этом удивительном пост:

Exclude A Filter

Просто реализовать пользовательский ExcludeFilterAttribute, а затем пользовательский номер ExcludeFilterProvider.

Чистый раствор и отлично работал для меня!

+1

Любое подобное решение для ядра aspnet? – smg

2

Создание пользовательского фильтра поставщика. Напишите класс, который будет реализовывать IFilterProvider. Этот интерфейс IFilterProvider имеет метод GetFilters, который возвращает фильтры, которые необходимо выполнить.

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

=========================================== ==================================
В 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); 
} 
0

Ну , Я думаю, что я работал над ASP.NET Core.
Вот код:

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

Соответствующий код находится в методе 'IsExcluded'.

0

По крайней мере, сегодня это довольно просто: чтобы исключить все действия фильтров из действия, просто добавьте OverrideActionFiltersAttribute.

Есть аналогичные атрибуты для других фильтров: OverrideAuthenticationAttribute, OverrideAuthorizationAttribute и OverrideExceptionAttribute.

Смотрите также https://www.strathweb.com/2013/06/overriding-filters-in-asp-net-web-api-vnext/

Смежные вопросы