前言
ASP.NET MVC 提供 ActionFilterAttribute 抽象類別,讓開發人員在 Action 執行之前或執行之後,可以注入自己的客製程式,例如寫入 LOG。以下紀錄它的用法。
客製 ActionFilterAttribute
1. 命名
在 ASP.NET 約定的用法,ActionFilterAttribute 的命名是在自訂名稱尾端加上「Attribute」,例如,HelloWorldAttribute。調用它時,可以這樣寫:[ HelloWorld ]或[ HelloWorldAttribute ]。
2. 自訂類別繼承 ActionFilterAttribute
ActionFilterAttribute 有四種虛擬方法,可讓我們覆寫:
- OnActionExecuting – 執行 Action 之前執行
- OnActionExecuted – 執行 Action 之後執行
- OnResultExecuting – 執行 Action Result 之前執行
- OnResultExecuted – 執行 Action Result 之後執行
假設我們寫一個繼承自 ActionFilterAttribute 的 HelloWorldAttribute 類別。在它的建構式,我們可以定義要輸入甚麼樣的參數。
參數有兩種定義方式:一是值參數、一是定位參數 (position parameter)。在 HelloWorldAttribute 建構式中我們定義兩個值參數,namd, id。
public string Name { get; set; } public int ID { get; set; } public Drinks OrderDrink{get;set;} //注意這個 Property public HelloWorldAttribute(string name, int id) { this.Name = name; this.ID = id; }
我們另外定義一個列舉 Drinks
public enum Drinks { TEA, CAFE, WATER }
以上這兩種定義有不同的參數寫法。
3. 完整範例
public enum Drinks { TEA, CAFE, WATER } public class HelloWorldAttribute : ActionFilterAttribute { public string Name { get; set; } public int ID { get; set; } public Drinks OrderDrink{get;set;} //注意這個 Property public HelloWorldAttribute(string name, int id) { this.Name = name; this.ID = id; } public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); } public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); } public override void OnResultExecuted(ResultExecutedContext filterContext) { string n = this.Name; string drinks = this.OrderDrink.ToString(); } public override void OnResultExecuting(ResultExecutingContext filterContext) { base.OnResultExecuting(filterContext); } }
在 Controller 注入
我們在 Controller 的 Action 注入 HelloWorldAttribute。可以看到前面兩個參數「jeff」、「5」 分別是上面定義的 HelloWorldAttribute 建構式的兩個參數:「name」、「id」。
第三個參數是所謂的定位參數,利用HelloWorldAttribute 類別定義好的 Property :OrderDrink ,指定一個 enum 的值。雖然在建構式並未定義。
public class HomeController : Controller { [HelloWorld("Jeff", 5, OrderDrink = Drinks.CAFE)] //注意 OrderDrink = Drinks.CAFE public ActionResult About() { ViewBag.Message = "Your application description page."; return View(); } }
如此一來,當執行 About 這個 Action,會先執行 HelloWorldAttribute 的方法 OnResultExecuted()。
(文章若有錯誤,歡迎指教。)