一年前寫了一篇短文ASP.NET MVC Action Filters,整理了Action Filter方面的資源,本篇文章詳細的描述Action Filter。Action Filter作為一個可以應用到Controller Action(或者是整個controller)上的屬性(Attribute),改變Action執行的行為,當應用於整個Controller上時,Controller上的所有Action都應用了同樣設定的Action。 使用Action Filter 可以處理緩衝、 驗證和錯誤處理您的操作使用宣告式程式設計模型的行為。
ASP.NET MVC Framework支援四種不同類型的Filter:
- Authorization filters – 實現
IAuthorizationFilter介面的屬性
.
- Action filters – 實現
IActionFilter介面的屬性
.
- Result filters – 實現
IResultFilter介面的屬性
.
- Exception filters – 實現
IExceptionFilter介面的
屬性.
Filter的預設的執行順序按上面的列表中順序進行。如驗證(authorization)Filter永遠都是最開始執行的,異常(exception)Filter永遠都是最後執行的,當然你也可以根據需要通過Order屬性設定過濾器執行的順序。
ASP.NET MVC Framework包括幾種Action Filter:
名稱 |
說明 |
OutputCacheAttribute |
類似於 Web Form中在 OutputCache 指令。 OutputCache 屬性允許在 MVC Framework 緩衝控制器的輸出。 |
ValidateInputAttribute |
類似於 Web Form中 ValidateRequest 屬性。 MVC 架構預設將為 檢查HTML 或其他危險輸入傳入的 HTTP 要求。 如果檢測到,將引發異常。 使用此屬性可以禁用請求驗證。 |
AuthorizeAttribute |
Authorize 屬性,可以對控制器操做的聲明性的授權檢查。 該屬性可以限制特定角色中的使用者的操作。 當您建立只應該給管理員角色中的使用者的操作時,您可以使用此屬性。預設使用的ASP.NET Membership服務,如果不使用ASP.NET 的Membership服務,可以繼承AuthorizeAttribute,重寫實現。 |
ValidateAntiForgeryTokenAttribute |
此屬性是一個解決方案以協助防止跨網站的請求攻擊 (CSRF)。 它允許驗證的 HTTP POST 為特定於使用者的標記在 Framework。 有關詳細資料 CSRFs,請參閱" 使用 ASP.NET MVC AntiForgeryToken() 協助器防止跨網站請求偽造 (CSFR)." |
驗證(authorization)filter用於實現在controller action上的驗證和授權,如Authorize filter就是一個驗證filter的例子;
Action filter包含一些邏輯,用於該action執行之前或者之後。比如可以使用一個action filter來修改action返回的view data;
Result filter包含一些邏輯,用於該action的view result執行之前和之後。比如可以修改一個view result在view被呈現到瀏覽器之前;
異常(Exception)Action用於處理異常資訊,同樣可以使用異常filter記錄錯誤記錄檔。
你同時可以建立自己的Action filter,比如說要實現一個自訂的驗證系統,那麼可能需要建立一個自訂的action filter,或者說當你需要改變controller action返回的view data的時候,也可以通過建立自訂action filter實現。
為了讓使用者更簡單的建立一個自訂Action filter,ASP.NET MVC Framework提供了一個基類ActionFilterAttribute,這個類實現了IActionFilter和IResultFilter介面,並且繼承了FilterAttribute類。從廣義上來說,在ASP.NET MVC Framework中,任何實現filter的類型都是action filter。
ActionFilterAttribute類有以下的方法可以重寫:
- OnActionExecuting – 在controller action執行之前調用
- OnActionExecuted – 在controller action執行之後調用
- OnResultExecuting – 在controller action result執行之前調用
- OnResultExecuted – 在controller action result執行之後調用
執行的順序如:
下面我們來介紹一個如何自訂一個Action Filter,這個樣本的代碼來自ASP.NET MVC 2樣本Tailspin Travel,實現的功能是Action的執行時間,頁面經常需要一個當前頁面執行時間的功能,這是一個非功能性需求,ASP.NET MVC上就可以使用自訂的ActionFilter來實現,從上面的介紹,就知道我們需要重寫OnActionExecuting和OnActionExecuted方法,代碼如下:
namespace Microsoft.Samples.Tailspin.Web
{
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Web.Mvc;
public class ExecutionTimingAttribute : ActionFilterAttribute
{
private bool timingEnabled = bool.Parse(ConfigurationManager.AppSettings["TimingEnabled"]);
private Stopwatch timer;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
if (this.timingEnabled)
{
this.timer = new Stopwatch();
this.timer.Start();
}
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
if (this.timingEnabled)
{
this.timer.Stop();
Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Action execution time: {0}ms", this.timer.ElapsedMilliseconds));
if (filterContext.Result is ViewResult)
{
((ViewResult)filterContext.Result).ViewData["ExecutionTime"] = this.timer.ElapsedMilliseconds;
}
}
}
}
}
通過一個配置項是否啟用頁面執行時間的控制,代碼非常簡單,使用Stopwatch來進行時間的計算,將執行的時間(毫秒為單位)存放到ViewData裡ViewData["ExecutionTime"] 。
在MasterPage裡頭尾部加入:
<div id="footer">
<% if(ViewData.ContainsKey("ExecutionTime")) { %>
<p>Execution Time: <%:ViewData["ExecutionTime"]%> ms.</p>
<%} %>
</div>
參考
Creating Custom Action Filters
Understanding Action Filters
asp.MVC 許可權設計