mvc4中的过滤器
過濾器(Filter)把附加邏輯注入到MVC框架的請求處理。實現(xiàn)了交叉關(guān)注。
交叉關(guān)注:用于整個應(yīng)用程序,又不適合放在某個局部位置的功能。
?
過濾器是.NET的注解屬性(Attribute),它們對請求處理管道添加了額外的步驟。
注解屬性是派生于System.Attribute的特殊的.NET類。
可以被附加到類、方法、屬性、字段等代碼元素上。其目的是把附加信息嵌入到已編譯的代碼中,以便在運行時讀回這些信息。
?
過濾器的基本類型:
| 過濾器類型 | 接口 | 默認實現(xiàn) | 描述 |
| Authorization | IAuthorizationFilter | AuthorizationAttribute | 最先運行 |
| Action | IActionFilter | ActionFilterAttribute | 在動作方法前后運行 |
| Result | IResultFilter | ActionResultAttribute | 在動作結(jié)果被執(zhí)行前后 |
| Exception | IExceptionFilter | HandlerErrorAttribute | 僅在過濾器、動作發(fā)生異常時 |
?
授權(quán)過濾器:IAuthorizationFilter
namespace System.Web.Mvc{// 摘要:定義授權(quán)篩選器所需的方法。public interface IAuthorizationFilter{// 摘要:在需要授權(quán)時調(diào)用。// 參數(shù):filterContext:篩選器上下文。void OnAuthorization(AuthorizationContext filterContext);}} View Code?
注意:
直接實現(xiàn)接口其實是一件非常危險的事;因此創(chuàng)建一個自定義AuthorizeAttribute子類,再實現(xiàn)授權(quán)代碼比較容易。
public class CustomAuthAttribute:AuthorizeAttribute{/// <summary>/// 是否對請求進行授權(quán)訪問的方式/// </summary>/// <param name="httpContext">對請求信息進行訪問的方法</param>protected override bool AuthorizeCore(HttpContextBase httpContext){return base.AuthorizeCore(httpContext);}} View Code?
直接實現(xiàn)IAuthorizationFilter接口的主要原因是為了獲取對傳遞給OnAuthorization()的AuthorizationContext的訪問,通過它可以獲得更廣泛的信息(路由細節(jié)、當(dāng)前控制器和動作方法信息)。使用接口的方式不僅有安全風(fēng)險且讓授權(quán)注解屬性中建立的邏輯與控制器緊密的耦合在一起,破壞關(guān)注分離,不便于維護。
?
內(nèi)建的授權(quán)過濾器:
雖然使用了AuthorizeAttribute類作為自定義過濾器的基礎(chǔ),但其AuthorizeCore()有自己的實現(xiàn)
當(dāng)直接使用AuthorizeAttribute時,可以使用它的public屬性來指定授權(quán)策略
AuthorizeAttribute屬性
| 名稱 | 類型 | 描述 |
| Users | String | 一個逗號分隔的用戶名列表,指定這些用戶可以訪問動作方法 |
| Roles | String | 一個逗號分隔的角色列表,用戶必須至少有一個角色 |
?
public class HomeController : Controller{[Authorize(Users ="admin,steve,jacqui",Roles ="admin")]public ActionResult Index(){return View();}} View Code?
異常過濾器:
namespace?System.Web.Mvc{
????// 摘要:定義異常篩選器所需的方法。
????public?interface?IExceptionFilter{
????????// 摘要:在發(fā)生異常時調(diào)用。
????????// 參數(shù):filterContext:
????????// ????篩選器上下文。
????????void?OnException(ExceptionContext?filterContext);
????}
}
當(dāng)一個未處理的異常出現(xiàn)時,OnException()被調(diào)用。該方法的參數(shù)是一個ExceptionContext?對象,此對象派生于ControllerContext,并提供了許多有用的屬性。
| 名稱 | 類型 | 描述 |
| Controller | ControllerBase | 返回請求的控制器對象 |
| HttpContext | HttpContextBase | 提供對請求細節(jié)的訪問及對響應(yīng)的訪問 |
| IsChildAction | Bool | 若是自動做則返回true |
| RequestContext | RequestContext | 提供對HttpContext和路由數(shù)據(jù)的訪問 |
| RouteData | RouteData | 返回請求的路由數(shù)據(jù) |
繼承自ControllerContext的屬性
| 名稱 | 類型 | 描述 |
| ActionDescripter | ActionDescripter | 提供動作方法的細節(jié) |
| Result | ActionResult | 用于動作方法的結(jié)果,通過非空值可取消請求 |
| Exception | Exception | 未處理的異常 |
| ExceptionHandled | Bool | 如果另一個過濾器已經(jīng)把這個異常標(biāo)記為已處理則返回true |
實現(xiàn)自定義異常過濾器
public?class?RangeExceptionAttribute?: FilterAttribute, IExceptionFilter{
????????public?void?OnException(ExceptionContext?filterContext){
}
}
使用內(nèi)建的異常過濾器:
HandleErrorAttribute屬性
| 名稱 | 類型 | 描述 |
| ExceptionType | Type | 由過濾器處理的異常類型 |
| View | String | 該過濾器渲染的視圖模板名 |
| Master | String | 在渲染這個過濾器的視圖時使用的布局名稱 |
準(zhǔn)備工作:
在web.config文件中啟用自定義錯誤時,HandleErrorAttribute過濾器才會生效,在<system.web>節(jié)點中添加一個customErrors屬性即可;
<system.web><!--定制錯誤頁aa.html--><customErrors mode="On" defaultRedirect="/Content/aa.html" /></system.web>?
Mode屬性的默認值是RemoteOnly在開發(fā)期間,HandleErrorAttribute將不會攔截異常,但當(dāng)應(yīng)用程序部署到產(chǎn)品服務(wù)器時,并從另一臺計算機發(fā)出請求時HandleErrorAttribute變生效
?[HandleError(ExceptionType =typeof(ArgumentNullException),View ="Null")]
????????public?ActionResult?Index(){
????????????return?View();
????}
在渲染視圖時HandleErrorAttribute過濾器會傳遞一個HandleErrorInfo視圖模型對象這是一個封裝了異常細節(jié)的封裝程序
| 名稱 | 類型 | 描述 |
| ActionName | String | 返回生成異常的Action名稱 |
| ControllerName | String | 返回生成異常的Controller名稱 |
| Exception | Exception | 返回此異常 |
?
@model HandleErrorInfo@{ ViewBag.Title = "Sorry";}<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width" /></head><body>@Model.Exception.StackTrace</body></html> View Code備注:使用HandleError過濾器時一定要包含Model.Exception.StackTrace否則視圖不會顯示給用戶,引用沒必要給用戶展示堆棧信息所以可以將該值放入div并隱藏
?
動作過濾器
用于任何目的的多用途過濾器
1 namespace System.Web.Mvc{ 2 3 // 摘要:定義操作篩選器中使用的方法。 4 5 public interface IActionFilter{ 6 7 // 摘要:在執(zhí)行操作方法后調(diào)用。 8 9 // 參數(shù):filterContext: 10 11 // 篩選器上下文。 12 13 void OnActionExecuted(ActionExecutedContext filterContext); 14 15 // 摘要:在執(zhí)行操作方法之前調(diào)用。 16 17 // 參數(shù):filterContext: 18 19 // 篩選器上下文。 20 21 void OnActionExecuting(ActionExecutingContext filterContext); 22 23 } 24 25 }?
ActionExecutingContext?屬性
| 名稱 | 類型 | 描述 |
| ActionDescriptor | ActionDescriptor | 動作方法的描述 |
| Result | ActionResult | 動作方法的結(jié)果,設(shè)置屬性非空值,過濾器可以取消請求 |
?
ActionExecutedContext?屬性
| 名稱 | 類型 | 描述 |
| ActionDescriptor | ActionDescriptor | 動作方法的描述 |
| Canceled | Bool | 如果該動作被另一個過濾器取消,則返回true |
| Exception | Exception | 返回由另一個過濾器或動作方法拋出的異常 |
| ExceptionHandled | Bool | 如果異常被處理返回true |
| Result | ActionResult | ? |
?
結(jié)果過濾器:
它會對動作方法所產(chǎn)生的結(jié)果進行操作
namespace System.Web.Mvc{// 摘要:定義結(jié)果篩選器所需的方法。public interface IResultFilter{// 摘要:在操作結(jié)果執(zhí)行后調(diào)用。// 參數(shù):filterContext:// 篩選器上下文。void OnResultExecuted(ResultExecutedContext filterContext);// 摘要:在操作結(jié)果執(zhí)行之前調(diào)用。// 參數(shù):filterContext:// 篩選器上下文。void OnResultExecuting(ResultExecutingContext filterContext);}}?
動作方法如何返回動作結(jié)果,讓用戶能夠?qū)幼鞣椒ǖ囊鈭D與動作方法的執(zhí)行分離。將結(jié)果過濾器運用于一個動作方法時會在動作方法返回結(jié)果時、但在執(zhí)行該動作結(jié)果之前調(diào)用OnResultExecuting。動作結(jié)果執(zhí)行之后調(diào)用OnResultExecuted
內(nèi)建的動作過濾器和結(jié)果過濾器
Mvc框架包含一個內(nèi)建的類,可以用來創(chuàng)建動作過濾器和結(jié)果過濾器,這個類的名稱ActionFilterAttribute
namespace System.Web.Mvc{// 摘要:表示篩選器特性的基類。public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter{// 摘要:在執(zhí)行操作方法后由 ASP.NET MVC 框架調(diào)用。// 參數(shù):filterContext:// 篩選器上下文。public virtual void OnActionExecuted(ActionExecutedContext filterContext);// 摘要:在執(zhí)行操作方法之前由 ASP.NET MVC 框架調(diào)用。// 參數(shù):filterContext:// 篩選器上下文。public virtual void OnActionExecuting(ActionExecutingContext filterContext);// 摘要:在執(zhí)行操作結(jié)果后由 ASP.NET MVC 框架調(diào)用。// 參數(shù):filterContext:// 篩選器上下文。public virtual void OnResultExecuted(ResultExecutedContext filterContext);// 摘要:在執(zhí)行操作結(jié)果之前由 ASP.NET MVC 框架調(diào)用。// 參數(shù):filterContext:// 篩選器上下文。public virtual void OnResultExecuting(ResultExecutingContext filterContext);}}使用這個類的唯一好處是不需要重寫和實現(xiàn)不打算使用的方法。除此之外,直接實現(xiàn)過濾器接口沒有任何好處
自定義實例:
public class ProfileAllAttribute: ActionFilterAttribute{private Stopwatch timer;public override void OnActionExecuting(ActionExecutingContext filterContext){timer = Stopwatch.StartNew();}public override void OnActionExecuted(ActionExecutedContext filterContext){timer.Stop();filterContext.HttpContext.Response.Write(string.Format("<div>Total elapsed time:{0}</div>", timer.Elapsed.TotalSeconds));}}public class HomeController : Controller{[ProfileAll]public ActionResult Index(){ return View();}} View Code?
其它過濾器屬性:
public?abstract?class?Controller?: ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer
?
過濾器的幾種實現(xiàn)形式:
①全局過濾器
在FilterConfig中直接注冊實現(xiàn)類
1 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 2 3 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 4 { 5 filters.Add(new HandleErrorAttribute()); 6 7 filters.Add(new MyCustomAttribute()); 8 }?
②實現(xiàn)接口
1 protected override void OnActionExecuting(ActionExecutingContext filterContext) 2 { 3 var contrllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 4 5 var actionName = filterContext.ActionDescriptor.ActionName; 6 7 var parameter = filterContext.ActionDescriptor.GetParameters(); 8 9 filterContext.HttpContext.Response.Write(contrllerName + "_" + actionName); 10 11 base.OnActionExecuting(filterContext); 12 } 13 14 protected override void OnActionExecuted(ActionExecutedContext filterContext) 15 { 16 base.OnActionExecuted(filterContext); 17 }?
③注解
?
1 public class MyCustomAttribute : FilterAttribute, IActionFilter 2 { 3 public void OnActionExecuted(ActionExecutedContext filterContext) 4 { 5 6 } 7 8 public void OnActionExecuting(ActionExecutingContext filterContext) 9 { 10 //1.如果result不為空,那么就return了。不執(zhí)行遞歸。。。 11 filterContext.Result = new ViewResult() 12 { 13 ViewName = "Error" 14 }; 15 } 16 }?
對過濾器執(zhí)行排序
過濾器是按類型執(zhí)行的其順序:授權(quán)-》Action-》result。如果有未處理異常,框架在任一階段都會執(zhí)行異常過濾器
1 namespace System.Web.Mvc 2 3 { 4 5 // 摘要:表示操作和結(jié)果篩選器特性的基類。 6 7 public abstract class FilterAttribute : Attribute, IMvcFilter{ 8 9 // 摘要: 獲取或設(shè)置一個值,該值指示是否可指定篩選器特性的多個實例。 10 11 // 返回結(jié)果:如果可指定篩選器特性的多個實例,則為 true;否則為 false。 12 13 public bool AllowMultiple { get; } 14 15 // 摘要: 獲取或者設(shè)置執(zhí)行操作篩選器的順序。 16 17 // 返回結(jié)果:執(zhí)行操作篩選器的順序。 18 19 public int Order { get; set; } 20 21 } 22 23 }?
?
內(nèi)建過濾器
| 過濾器 | 描述 |
| RequireHttps | 強迫Action使用Https協(xié)議 |
| OutputCache | 緩存一個Action的 |
| ValidateInputand ValidationAntiForgeryToken | 與安全性有關(guān)的授權(quán)過濾器 |
| AsyncTimeout NoAsyncTimeout | 用戶異步控制器 |
| ChildActionOnlyAttribute | 一個支持Html.action和Html.RenderAction輔助器方法的過濾器 |
RequireHttps
RequireHttps過濾器讓Action強制使用HTTPS協(xié)議。他將用戶瀏覽器重定向到同一個動作,但使用‘https://’協(xié)議前綴
在形成不安全請求時,重寫HandledNonHttpsRequest(),以創(chuàng)建自定義行為,該過濾器僅用于GET請求,POST則會丟掉數(shù)據(jù);該過濾器時授權(quán)過濾器
轉(zhuǎn)載于:https://www.cnblogs.com/cuijl/p/6523595.html
總結(jié)
- 上一篇: 第二周作业-影评、靶机和攻击机的安装与配
- 下一篇: VS 2017 安装测试