2012-03-31 44 views
56

Tôi đã thiết lập bộ lọc toàn cục cho tất cả các hành động điều khiển của mình, trong đó tôi mở và đóng các phiên NHibernate. 95% của các hành động này cần một số truy cập cơ sở dữ liệu, nhưng 5% không. Có cách nào dễ dàng để vô hiệu hóa bộ lọc toàn cầu này cho 5% đó không. Tôi có thể đi theo một cách khác và chỉ trang trí những hành động cần cơ sở dữ liệu, nhưng điều đó sẽ hoạt động hiệu quả hơn nhiều.Làm thế nào để vô hiệu hóa một bộ lọc toàn cầu trong ASP.Net MVC chọn lọc

+1

Điều gì về việc tạo một hành động khác và trang trí 5% với điều này. Một cái gì đó như NHibernateNotRequiredAttribute()? – dreza

+0

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

Trả lời

109

Bạn có thể viết một thuộc tính marker:

public class SkipMyGlobalActionFilterAttribute : Attribute 
{ 
} 

và sau đó trong bài kiểm tra bộ lọc hành động toàn cầu của bạn cho sự hiện diện của dấu này vào hành động:

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

và sau đó nếu bạn muốn loại trừ một số hành động từ bộ lọc chung chỉ cần trang trí nó với thuộc tính điểm đánh dấu:

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

Giải pháp thực sự tuyệt vời. Tôi tự hỏi làm thế nào tôi không nghĩ về điều này một mình. Cảm ơn. – zszep

+1

Giải pháp đơn giản. Cảm ơn! –

+0

Giải pháp tuyệt vời. Bạn tiết kiệm thời gian của tôi. :) – Ankita

1

Bạn có thể thay đổi mã bộ lọc của bạn như thế này:

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

Và sử dụng nó:

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

Đó là một cách để thực hiện, nhưng hơi khó duy trì theo thời gian – zszep

+1

Nếu bạn thay đổi tên hành động của bạn và quên thay đổi nó trong cách sử dụng thuộc tính, trình biên dịch sẽ không cảnh báo bạn.Điều này là rất có khả năng gây ra đau đớn bảo trì.Tôi thích câu trả lời của Darin kể từ khi bạn không cần phải xác định các hành động bằng tay – Nashenas

16

Bạn cũng có thể làm gì được mô tả trong bài viết này awesome:

Exclude A Filter

Chỉ cần thực hiện tùy chỉnh ExcludeFilterAttribute và sau đó tùy chỉnh ExcludeFilterProvider.

Giải pháp làm sạch và làm việc tuyệt vời cho tôi!

+1

Bất kỳ giải pháp tương tự cho lõi aspnet? – smg

2

Tạo một nhà cung cấp tùy chỉnh Filter. Viết một lớp sẽ thực hiện IFilterProvider. Giao diện IFilterProvider này có phương thức GetFilters trả về các bộ lọc cần được thực hiện.

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

======================= ==================================
Trong 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

Vâng , Tôi nghĩ rằng tôi đã nhận nó làm việc cho ASP.NET Core.
Dưới đây là các mã:

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

Mã liên quan là trong phương pháp 'IsExcluded'.

0

Ít nhất hiện nay, điều này khá dễ dàng: để loại trừ tất cả các bộ lọc hành động khỏi một hành động, chỉ cần thêm Ghi đè hành độngFiltersAttribute.

Có thuộc tính tương tự cho các bộ lọc khác: OverrideAuthenticationAttribute, OverrideAuthorizationAttributeOverrideExceptionAttribute.

Xem thêm https://www.strathweb.com/2013/06/overriding-filters-in-asp-net-web-api-vnext/

Các vấn đề liên quan