2009-01-24 68 views
4

我一直在做一些有關動作過濾器的研究,並想知道是否有方法將它們以編程方式添加到控制器?ASP.NET MVC - 以編程方式添加動作過濾器

給予一定的情況下,我想,如果日誌記錄在web.config配置以增加日誌過濾器,否則我不希望過濾器在每個操作方法的執行鏈存在。

我明白我可以把實際的過濾器代碼本身檢查,看看是否啓用日誌記錄,但不想這樣做是可能的。

非常感謝!

回答

1

更好的解決方案是使用null object pattern

你的過濾器通常會登錄(它的工作是記錄,而不是決定如何記錄或什麼記錄到,不一定),但默認情況下實際的記錄將是不執行任何操作的實現。如果已配置,則記錄器實例將是按配置記錄的實現。

一個簡單的工廠可以決定將哪個記錄器實現傳遞給過濾器或者任何IOC容器可以配置爲處理它。

+0

雖然這確實解決了一般情況並解決了OP的問題,但它並沒有真正回答這個問題。我來到這裏尋找基於問題標題的過濾器編程操作指南。 – Sentinel 2016-09-05 10:19:00

0

我從未以編程方式給方法添加屬性,因爲它看起來像是一個低效的噩夢,我總是找到一個更好的選擇。

你需要在某處做檢查,雖然我同意屬性代碼可能不是最好的地方,但它並不是特別糟糕。如果你真的不想這樣做,那麼你可以抽象出日誌代碼,以便它只能使用已啓用的各種條目,然後由你決定要在多少體系結構中放置它。

1
[LogRequest] 
    [PermissionRequired(Permits.View_users, Permits.Edit_users)] 
    public ActionResult Edit(int id, .....) 
      { 
      ... 
      } 

    public class PermissionRequired : ActionFilterAttribute, IActionFilter 
{ 
    private readonly PermissionsList permits; 

    public PermissionRequired(params Permits[] perm) 
    { 
     permits = new PermissionsList(perm); 
    } 

    #region IActionFilter Members 

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     ... 
     IEnumerable<int> intersection = (from up in User.CurrentUser.UserPermission 
             select up.PermissionID).ToList().Intersect(permits.Cast<int>()); 
     if (intersection.Count() != permits.Count) 
     { 
      filterContext.Result = null; 
      HttpContext.Current.Response.Redirect("/Error/PermissionsRequired.htm"); 
     } 
    } 

    #endregion 
} 
0

您可以着手創建自己的ActionInvoker實現,它是處理調用過濾器和操作方法的類。話雖如此,我認爲這不是一個好的解決方案。它違反了關注的分離。最好讓您的日誌記錄操作篩選器確定是否應該記錄日誌。

0

我一直在尋找通過新的Oxite代碼(最後一個版本遭受了重大的重構由於大量的批評者)和他們做一些有趣的事情。 他們創建自己的ActionFilterRepository來保存不同的過濾器(IActionFilters,IAuthorizationFilters等)。在自定義的ControllerActionInvoker中,GetFilters方法被覆蓋,並將存儲庫中的過濾器添加到當前集合中。這樣,他們有一套全局過濾器應用於每個動作和控制器。

您可以看到自定義調用代碼在這裏: OxiteControllerActionInvoker.cs

和示例在這裏進行過濾: LocalizationActionFilter.cs

希望這有助於。

相關問題