https://blog.csdn.net/knqiufan/article/details/82413885
本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/knqiufan/article/details/82413885參考文章:1、https://www.cnblogs.com/webapi/p/5669057.html
? ? ? ? ? ? ? ? ? 2、https://shiyousan.com/post/635835285087587126
在MVC中有一個過濾機制,可以編寫為過濾器或攔截器,用于對在某個Action執行前后再執行的動作。
過濾器繼承自ActionFilterAttribute類(命名空間是System.Web.Mvc)
ActionFilterAttribute類是一個特性類。
在菜鳥教程中,對特性是這么描述的:(鏈接:http://www.runoob.com/csharp/csharp-attribute.html)
特性(Attribute)是用于在運行時傳遞程序中各種元素(比如類、方法、結構、枚舉、組件等)的行為信息的聲明性標簽。您可以通過使用特性向程序添加聲明性信息。一個聲明性標簽是通過放置在它所應用的元素前面的方括號([ ])來描述的。
特性(Attribute)用于添加元數據,如編譯器指令和注釋、描述、方法、類等其他信息。.Net 框架提供了兩種類型的特性:預定義特性和自定義特性
ActionFilterAttribute實現了兩個很重要的接口:IActionFilter,IResultFilter
ActionFilterAttribute實現了它們,那么自然也擁有這四個方法
首先,IActionFilter接口的 OnActionExecuting方法和OnActionExecuted方法:
? ? ? ? //該方法會在action方法執行之前調用??? ? ? ? public override void OnActionExecuting(ActionExecutingContext filterContext)??? ? ? ? {??? ? ? ? ? ? filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法調用錢執行<br/>");??? ? ? ? ? ? base.OnActionExecuting(filterContext);??? ? ? ? }????? ? ? ? //該方法會在action方法執行之后調用??? ? ? ? public override void OnActionExecuted(ActionExecutedContext filterContext)??? ? ? ? {??? ? ? ? ? ? filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在action方法調用后執行<br/>");??? ? ? ? ? ? base.OnActionExecuted(filterContext);??? ? ? ? }??調用的時候直接這么調用:
[MyFilter]??public void FilterTest()??{??? ? ?Response.Write("我是action方法,在這里執行了</br>");??}要在一個action方法中使用一個過濾器,只要在該方法上貼一個過濾器的標簽就ok了。
?
但是有時候我們會有這樣的一需求:
在過濾器中當遇到了貼了某某標簽的action方法就跳過不進行驗證
這怎么辦呢?
可以通過filterContext的ActionDescriptor屬性類完成這易操作
ActionDescriptor顧名思義,action方法的描述著
在ActionDescriptor中我們可以拿到相應的action方法信息,甚至還可以拿到一個控制器描述著ControllerDescriptor
代碼如下:
? ? ? ? //該方法會在action方法執行之前調用??? ? ? ? public override void OnActionExecuting(ActionExecutingContext filterContext)??? ? ? ? {??? ? ? ? ? ? filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法調用前執行<br/>");??? ? ? ? ? ? //判斷該action方法時候有貼上MyFilter1Attribute標簽??? ? ? ? ? ? if (filterContext.ActionDescriptor.IsDefined(typeof (MyFilter1Attribute),false))??? ? ? ? ? ? {??? ? ? ? ? ? ? ? //如果有,為該action方法直接返回ContentResult,則該action方法在這里就有了返回值,相當于在這里就結束了,不會在去執行之后的方法,如:OnActionExecuted等??? ? ? ? ? ? ? ? filterContext.Result = new ContentResult();??? ? ? ? ? ? }??? ? ? ? ? ? base.OnActionExecuting(filterContext);??? ? ? ? }這樣action方法中和OnActionExecuted中的Response.Write都沒有被執行,也就是說,該action方法被跳過了
?
接下來看看IResultFilter接口的兩個方法:OnResultExecuting方法和OnResultExecuted方法
? ? ? ? //在action方法返回結果之后執行??? ? ? ? public override void OnResultExecuting(ResultExecutingContext filterContext)??? ? ? ? {??? ? ? ? ? ? filterContext.HttpContext.Response.Write("我是OnActionExecuting,我action方法返回結果之前執行<br/>");??? ? ? ? ? ? base.OnResultExecuting(filterContext);??? ? ? ? }????? ? ? ? //在action方法返回結果之前前執行??? ? ? ? public override void OnResultExecuted(ResultExecutedContext filterContext)??? ? ? ? {??? ? ? ? ? ? filterContext.HttpContext.Response.Write("我是OnResultExecuted,我在action方法返回結果之后執行<br/>");??? ? ? ? ? ? base.OnResultExecuted(filterContext);??? ? ? ? }使用方法和IActionFilter的使用方法是一樣的。
IResultFilter接口中的方法和IActionFilter方法的區別就是執行位置不一樣。
?
mvc框架中還有一個過濾器,他就是權限過濾器AuthorizeAttribute
該過濾器在所有action方法過濾器之前執行,也就是說,提供了一個可以超前驗證的方法
我們在添加一個新的過濾器類,并繼承自AuthorizeAttribute
重寫其OnAuthorization方法如下:
【注意,把基類的OnAuthorization方法去掉,因為我們并不需要,而且留著可能會出現一些錯誤異常】
? ? public class MyFilterReAttribute:AuthorizeAttribute??? ? {??? ? ? ? //在所有action方法過濾器之前執行??? ? ? ? public override void OnAuthorization(AuthorizationContext filterContext)??? ? ? ? {??? ? ? ? ? ? filterContext.HttpContext.Response.Write("我是OnAuthorization,在所有action方法過濾器之前執行<br/>");??? ? ? ? ? ? //base.OnAuthorization(filterContext);??? ? ? ? }??? ? }? ? ? ? [MyFilter]??? ? ? ? [MyFilterRe]??? ? ? ? public ActionResult FilterTest()??? ? ? ? {??? ? ? ? ? ? Response.Write("我是action方法的Response.Write,在這里執行了~~</br>");??? ? ? ? ? ? return View();??? ? ? ? }運行之后:
這樣我們就可以根據需要選擇合適的方法進行權限驗證,過濾,攔截等等動作。
如果控制器中的所有action都需要驗證等,那么就可以在控制類中統一貼上標簽:
這樣該控制器中的所有action方法都會進行驗證
那么,如果每個控制器都需要驗證、過濾、攔截呢?
這個時候就需要打開App_Start文件夾,打開FilterConfig類,在這里面添加全局的過濾器:
下面簡單說一下FilterConfig類。
在Global.asax文件中,FilterConfig類是全局Filter的管理器:
FilterConfig類在項目的App_Start文件夾下:
默認已經注冊了一個HandleErrorAttribute類(異常過濾器),我們可以通過GlobalFilterCollection 類對全局過濾器進行管理,比如對全局過濾器進行注冊、刪除和管理運行順序等操作
【備注:所謂的全局過濾器,就是會應用到所有操作方法和控制器的過濾器,一旦在FilterConfig類中注冊了某個過濾器,就不需要再額外去控制器中聲明。】
?---------------------?作者:knqiufan?來源:CSDN?原文:https://blog.csdn.net/knqiufan/article/details/82413885?版權聲明:本文為博主原創文章,轉載請附上博文鏈接!