2014-09-25 44 views
4

這裏是一個smaple動作過濾器,我們知道當我們編寫動作過濾器時,我們需要像這樣對裝飾控制器進行裝飾,以便爲任何特定的控制器實現它,但是說我想知道有沒有什麼辦法來編寫動作過濾器,它將適用於所有控制器,而且我不需要用動作過濾器屬性來裝飾控制器。任何想法。如何爲所有控制器編寫動作過濾器

[LogActionFilter] 
public class HomeController : Controller 
{} 

public class LogActionFilter : ActionFilterAttribute 

    { 
      public override void OnActionExecuting(ActionExecutingContext filterContext) 
      { 
       Log("OnActionExecuting", filterContext.RouteData);  
      } 

      public override void OnActionExecuted(ActionExecutedContext filterContext) 
      { 
       Log("OnActionExecuted", filterContext.RouteData);  
      } 

      private void Log(string methodName, RouteData routeData) 
      { 
       var controllerName = routeData.Values["controller"]; 
       var actionName = routeData.Values["action"]; 
       var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName); 
       Debug.WriteLine(message, "Action Filter Log"); 
      } 

    } 

回答

8
public class LogActionFilterAttribute : IActionFilter 
    { 
     public void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
      Log("OnActionExecuted", filterContext.RouteData);  
     } 

     public void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      Log("OnActionExecuting", filterContext.RouteData); 
     } 

     private void Log(string methodName, RouteData routeData) 
     { 
      var controllerName = routeData.Values["controller"]; 
      var actionName = routeData.Values["action"]; 
      var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName); 
      Debug.WriteLine(message, "Action Filter Log"); 
     } 
    } 

public class MvcApplication : System.Web.HttpApplication 
    { 
     protected void Application_Start() 
     { 
      GlobalFilters.Filters.Add(new LogActionFilterAttribute()); 
     } 
    } 
+0

如果我們使用GlobalFilters,那麼我的操作過濾器將被調用所有控制器的操作方法? – Thomas 2014-09-25 07:52:19

+0

是的,應該實施IActionFilter。實際上,您可以看到在創建MVC應用程序時自動生成的FilterConfig.cs中註冊的HandleErrorAttribute。 – 2014-09-25 07:58:59

+0

執行IActionFilter的手段?我的所有控制器需要擴展IActionFilter?不是很清楚你想做什麼。如果可能的話包括一個小的完整代碼謝謝 – Thomas 2014-09-25 08:29:15

3

對於您的情況,你可以只是做一個定製BaseController,把你的[LogActionFilter]屬性上定製Basecontroller和繼承定製Basecontroller所有控制器,如下圖所示:

[LogActionFilter] 
public class MyBaseController : Controller 
{ 

} 

public class MyOtherController : MyBaseController //<----instead of using Controller as base use MyBaseController as base class 
{ 
    public ActionResult Index() 
    { 
     // ... 
    } 
} 

這種方法的優點是你必須把你的自定義[LogActionFilter]屬性只在一個地方,即只在自定義BaseController。

+0

你能寫一點代碼來理解你想說什麼嗎?謝謝 – Thomas 2014-09-25 07:51:29

+0

@ Thomas ..查看更新的答案。 – 2014-09-25 07:53:23

+0

在這裏,我看到你用LogActionFilter裝飾MyBaseController,並再次在basecontroller中寫入OnActionExecuting()例程,然後LogActionFilter代碼如何顯示。在我的問題中,我在LogActionFilter類中編寫了OnActionExecuting()例程。我需要在2個地方重複LogActionFilter代碼? – Thomas 2014-09-25 08:27:49

0

如果您已經從基本控制器子類,你並不需要一個過濾器屬性或註冊任何東西。你可以只覆蓋所需的方法,例如,

public class BaseController : Controller { 
    protected override void OnActionExecuting(ActionExecutingContext filterContext) { 
     ViewBag.SomeValue = "glorp frob blizz nunk"; 
     // Access the controller, parameters, querystring, etc. from the filterContext 
     base.OnActionExecuting(filterContext); 
    } 
} 

然後,每一個從它的子類控制器將運行方法:

public sealed class GlorpController : BaseController { 
    public ActionResult Index() => View(); 
} 

畫面將會很樂意看到ViewBag.SomeValue值。

相關問題