在項目中,在Action執行前或者執行后,通常我們會做一些特殊的操作(比如身份驗證,日志,異常,行為截取等)。
微軟並不想讓MVC開發人員去關心和寫這部分重復的代碼,所以在MVC項目中我們就可以直接使用它提供的Filter的特性幫我們解決。

在項目中的Models文件夾中創建一個特性類,MyActionFilterAttribute.cs特性類必須以Attribute結尾。
繼承System.Web.Mvc.ActionFilterAttribute抽象類,並重寫其中的四個方法。

添加一個Home控制器,在Index的Action頭部添加[MyActionFilter]過濾器聲明。代碼如下:


過濾器還可以添加在控制器級別。在HomeController頭部添加,可以給整個HomeController內部的所有的Action添加過濾功能。
如果同時在控制器與Action上都設置了過濾器,離的近的優先級別更高。 想要全局網站每個頁面都應用過濾器,可以在App_Start目錄中的FilterConfig.cs類中添加全局的過濾器,代碼如下:

雖然設為全局的過濾器,但是按照優先級別每一個Action或ActionResult執行前后都會匹配到最近(優先級最高)的一個過濾器執行,如果我們希望所有的過濾器都執行,我們可以在特性類上打上標簽。

異常過濾器
MVC站點出現異常的時候,會自動執行異常過濾器中的方法。
在FilterConfig.cs中,MVC已經將一個異常過濾器定義成全局的了 filters.Add(new HandleErrorAttribute()); 轉到定義查看:
其中包含一個可以重寫的虛方法。 public virtual void OnException(ExceptionContext filterContext);

將自己寫的異常過濾器注冊到全局。
然后在控制器的Action手動拋出異常 throw new Exception(“測試異常過濾”);
Ctrl+F5運行項目,訪問你添加異常的Action測試一下。(F5運行會將異常拋出)
身份驗證的案例:
Model中:
public class MyFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); HttpContextBase http = filterContext.HttpContext; //HttpContext.Current if (http.Request.Cookies["name"] == null) //如果名字為空,就去/FilterDemo/Index這里 http.Response.Redirect("/FilterDemo/Index"); //HttpContext.Current.Server //string name = HttpContext.Current.Request.Cookies["name"].Value; //有名字 //對cookies里面的值解下碼 string msg = http.Server.UrlDecode(http.Request.Cookies["name"].Value) + "用戶" + DateTime.Now.ToString() + "時間" + http.Request.RawUrl + "地址\r\n"; StreamWriter sw = File.AppendText(@"E:\log.txt"); //如果沒有log.txt文件就創建,有的話就追加在后面 sw.Write(msg);//將字符串寫入流 sw.Flush();//清理緩存 sw.Dispose();//釋放流 } }
Controller:
public class FilterDemoController : Controller { // // GET: /FilterDemo/ public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(string name) { ViewBag.name = name; Response.Cookies["name"].Value = Server.UrlEncode(name); //對中文進行編碼,Cookies里面存的就是編碼完成后的內容 return View(); } [MyFilter] //對此方法進行過濾 public ActionResult List() { string name=Server.UrlDecode(Request.Cookies["name"].Value); //用Cookies的時候解碼下 ViewBag.name =name; return View(); } }
Index:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <div> <h1>首頁 @ViewBag.name</h1> <hr /> @Html.ActionLink("Goto list....", "list"); <form action="@Url.Action("Index")" method="post"> <input type="text" name="name" value=" " /> <input type="submit" value="登入" /> </form> </div> </body> </html>
List:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>List</title> </head> <body> <div> <h1>詳細頁 </h1> <hr /> <div>@ViewBag.name 這是數據....</div> </div> </body> </html>
