您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何在ASP.NET mvc4項(xiàng)目中使用過(guò)濾器,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
mvc4中的過(guò)濾器
過(guò)濾器(Filter)把附加邏輯注入到MVC框架的請(qǐng)求處理。實(shí)現(xiàn)了交叉關(guān)注。
交叉關(guān)注:用于整個(gè)應(yīng)用程序,又不適合放在某個(gè)局部位置的功能。
過(guò)濾器是.NET的注解屬性(Attribute),它們對(duì)請(qǐng)求處理管道添加了額外的步驟。
注解屬性是派生于System.Attribute的特殊的.NET類(lèi)。
可以被附加到類(lèi)、方法、屬性、字段等代碼元素上。其目的是把附加信息嵌入到已編譯的代碼中,以便在運(yùn)行時(shí)讀回這些信息。
過(guò)濾器的基本類(lèi)型:
過(guò)濾器類(lèi)型 | 接口 | 默認(rèn)實(shí)現(xiàn) | 描述 |
Authorization | IAuthorizationFilter | AuthorizationAttribute | 最先運(yùn)行 |
Action | IActionFilter | ActionFilterAttribute | 在動(dòng)作方法前后運(yùn)行 |
Result | IResultFilter | ActionResultAttribute | 在動(dòng)作結(jié)果被執(zhí)行前后 |
Exception | IExceptionFilter | HandlerErrorAttribute | 僅在過(guò)濾器、動(dòng)作發(fā)生異常時(shí) |
授權(quán)過(guò)濾器:IAuthorizationFilter
namespace System.Web.Mvc{ // 摘要:定義授權(quán)篩選器所需的方法。 public interface IAuthorizationFilter{ // 摘要:在需要授權(quán)時(shí)調(diào)用。 // 參數(shù):filterContext:篩選器上下文。 void OnAuthorization(AuthorizationContext filterContext); } }
注意:
直接實(shí)現(xiàn)接口其實(shí)是一件非常危險(xiǎn)的事;因此創(chuàng)建一個(gè)自定義AuthorizeAttribute子類(lèi),再實(shí)現(xiàn)授權(quán)代碼比較容易。
public class CustomAuthAttribute:AuthorizeAttribute{ /// <summary> /// 是否對(duì)請(qǐng)求進(jìn)行授權(quán)訪(fǎng)問(wèn)的方式 /// </summary> /// <param name="httpContext">對(duì)請(qǐng)求信息進(jìn)行訪(fǎng)問(wèn)的方法</param> protected override bool AuthorizeCore(HttpContextBase httpContext){ return base.AuthorizeCore(httpContext); } }
直接實(shí)現(xiàn)IAuthorizationFilter接口的主要原因是為了獲取對(duì)傳遞給OnAuthorization()的AuthorizationContext的訪(fǎng)問(wèn),通過(guò)它可以獲得更廣泛的信息(路由細(xì)節(jié)、當(dāng)前控制器和動(dòng)作方法信息)。使用接口的方式不僅有安全風(fēng)險(xiǎn)且讓授權(quán)注解屬性中建立的邏輯與控制器緊密的耦合在一起,破壞關(guān)注分離,不便于維護(hù)。
內(nèi)建的授權(quán)過(guò)濾器:
雖然使用了AuthorizeAttribute類(lèi)作為自定義過(guò)濾器的基礎(chǔ),但其AuthorizeCore()有自己的實(shí)現(xiàn)
當(dāng)直接使用AuthorizeAttribute時(shí),可以使用它的public屬性來(lái)指定授權(quán)策略
AuthorizeAttribute屬性
名稱(chēng) | 類(lèi)型 | 描述 |
Users | String | 一個(gè)逗號(hào)分隔的用戶(hù)名列表,指定這些用戶(hù)可以訪(fǎng)問(wèn)動(dòng)作方法 |
Roles | String | 一個(gè)逗號(hào)分隔的角色列表,用戶(hù)必須至少有一個(gè)角色 |
public class HomeController : Controller{ [Authorize(Users ="admin,steve,jacqui",Roles ="admin")] public ActionResult Index(){ return View(); } }
異常過(guò)濾器:
namespace System.Web.Mvc{ // 摘要:定義異常篩選器所需的方法。 public interface IExceptionFilter{ // 摘要:在發(fā)生異常時(shí)調(diào)用。 // 參數(shù):filterContext: // 篩選器上下文。 void OnException(ExceptionContext filterContext); } }
當(dāng)一個(gè)未處理的異常出現(xiàn)時(shí),OnException()被調(diào)用。該方法的參數(shù)是一個(gè)ExceptionContext 對(duì)象,此對(duì)象派生于ControllerContext,并提供了許多有用的屬性。
名稱(chēng) | 類(lèi)型 | 描述 |
Controller | ControllerBase | 返回請(qǐng)求的控制器對(duì)象 |
HttpContext | HttpContextBase | 提供對(duì)請(qǐng)求細(xì)節(jié)的訪(fǎng)問(wèn)及對(duì)響應(yīng)的訪(fǎng)問(wèn) |
IsChildAction | Bool | 若是自動(dòng)做則返回true |
RequestContext | RequestContext | 提供對(duì)HttpContext和路由數(shù)據(jù)的訪(fǎng)問(wèn) |
RouteData | RouteData | 返回請(qǐng)求的路由數(shù)據(jù) |
繼承自ControllerContext的屬性
名稱(chēng) | 類(lèi)型 | 描述 |
ActionDescripter | ActionDescripter | 提供動(dòng)作方法的細(xì)節(jié) |
Result | ActionResult | 用于動(dòng)作方法的結(jié)果,通過(guò)非空值可取消請(qǐng)求 |
Exception | Exception | 未處理的異常 |
ExceptionHandled | Bool | 如果另一個(gè)過(guò)濾器已經(jīng)把這個(gè)異常標(biāo)記為已處理則返回true |
實(shí)現(xiàn)自定義異常過(guò)濾器
public class RangeExceptionAttribute : FilterAttribute, IExceptionFilter{ public void OnException(ExceptionContext filterContext){ } }
使用內(nèi)建的異常過(guò)濾器:
HandleErrorAttribute屬性
名稱(chēng) | 類(lèi)型 | 描述 |
ExceptionType | Type | 由過(guò)濾器處理的異常類(lèi)型 |
View | String | 該過(guò)濾器渲染的視圖模板名 |
Master | String | 在渲染這個(gè)過(guò)濾器的視圖時(shí)使用的布局名稱(chēng) |
準(zhǔn)備工作:
在web.config文件中啟用自定義錯(cuò)誤時(shí),HandleErrorAttribute過(guò)濾器才會(huì)生效,在<system.web>節(jié)點(diǎn)中添加一個(gè)customErrors屬性即可;
<system.web> <!--定制錯(cuò)誤頁(yè)aa.html--> <customErrors mode="On" defaultRedirect="/Content/aa.html" /> </system.web>
Mode屬性的默認(rèn)值是RemoteOnly在開(kāi)發(fā)期間,HandleErrorAttribute將不會(huì)攔截異常,但當(dāng)應(yīng)用程序部署到產(chǎn)品服務(wù)器時(shí),并從另一臺(tái)計(jì)算機(jī)發(fā)出請(qǐng)求時(shí)HandleErrorAttribute變生效
[HandleError(ExceptionType =typeof(ArgumentNullException),View ="Null")] public ActionResult Index(){ return View(); }
在渲染視圖時(shí)HandleErrorAttribute過(guò)濾器會(huì)傳遞一個(gè)HandleErrorInfo視圖模型對(duì)象這是一個(gè)封裝了異常細(xì)節(jié)的封裝程序
名稱(chēng) | 類(lèi)型 | 描述 |
ActionName | String | 返回生成異常的Action名稱(chēng) |
ControllerName | String | 返回生成異常的Controller名稱(chēng) |
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>
備注:使用HandleError過(guò)濾器時(shí)一定要包含Model.Exception.StackTrace否則視圖不會(huì)顯示給用戶(hù),引用沒(méi)必要給用戶(hù)展示堆棧信息所以可以將該值放入div并隱藏
動(dòng)作過(guò)濾器
用于任何目的的多用途過(guò)濾器
namespace System.Web.Mvc{ // 摘要:定義操作篩選器中使用的方法。 public interface IActionFilter{ // 摘要:在執(zhí)行操作方法后調(diào)用。 // 參數(shù):filterContext: // 篩選器上下文。 void OnActionExecuted(ActionExecutedContext filterContext); // 摘要:在執(zhí)行操作方法之前調(diào)用。 // 參數(shù):filterContext: // 篩選器上下文。 void OnActionExecuting(ActionExecutingContext filterContext); } }
ActionExecutingContext 屬性
名稱(chēng) | 類(lèi)型 | 描述 |
ActionDescriptor | ActionDescriptor | 動(dòng)作方法的描述 |
Result | ActionResult | 動(dòng)作方法的結(jié)果,設(shè)置屬性非空值,過(guò)濾器可以取消請(qǐng)求 |
ActionExecutedContext 屬性
名稱(chēng) | 類(lèi)型 | 描述 |
ActionDescriptor | ActionDescriptor | 動(dòng)作方法的描述 |
Canceled | Bool | 如果該動(dòng)作被另一個(gè)過(guò)濾器取消,則返回true |
Exception | Exception | 返回由另一個(gè)過(guò)濾器或動(dòng)作方法拋出的異常 |
ExceptionHandled | Bool | 如果異常被處理返回true |
Result | ActionResult |
|
結(jié)果過(guò)濾器:
它會(huì)對(duì)動(dòng)作方法所產(chǎn)生的結(jié)果進(jìn)行操作
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); } }
動(dòng)作方法如何返回動(dòng)作結(jié)果,讓用戶(hù)能夠?qū)?dòng)作方法的意圖與動(dòng)作方法的執(zhí)行分離。將結(jié)果過(guò)濾器運(yùn)用于一個(gè)動(dòng)作方法時(shí)會(huì)在動(dòng)作方法返回結(jié)果時(shí)、但在執(zhí)行該動(dòng)作結(jié)果之前調(diào)用OnResultExecuting。動(dòng)作結(jié)果執(zhí)行之后調(diào)用OnResultExecuted
內(nèi)建的動(dòng)作過(guò)濾器和結(jié)果過(guò)濾器
Mvc框架包含一個(gè)內(nèi)建的類(lèi),可以用來(lái)創(chuàng)建動(dòng)作過(guò)濾器和結(jié)果過(guò)濾器,這個(gè)類(lèi)的名稱(chēng)ActionFilterAttribute
namespace System.Web.Mvc{ // 摘要:表示篩選器特性的基類(lèi)。 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); } }
使用這個(gè)類(lèi)的唯一好處是不需要重寫(xiě)和實(shí)現(xiàn)不打算使用的方法。除此之外,直接實(shí)現(xiàn)過(guò)濾器接口沒(méi)有任何好處
自定義實(shí)例:
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();} }
其它過(guò)濾器屬性:
public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer
過(guò)濾器的幾種實(shí)現(xiàn)形式:
①全局過(guò)濾器
在FilterConfig中直接注冊(cè)實(shí)現(xiàn)類(lèi)
②實(shí)現(xiàn)接口
③注解
對(duì)過(guò)濾器執(zhí)行排序
過(guò)濾器是按類(lèi)型執(zhí)行的其順序:授權(quán)-》Action-》result。如果有未處理異常,框架在任一階段都會(huì)執(zhí)行異常過(guò)濾器
namespace System.Web.Mvc { // 摘要:表示操作和結(jié)果篩選器特性的基類(lèi)。 public abstract class FilterAttribute : Attribute, IMvcFilter{ // 摘要: 獲取或設(shè)置一個(gè)值,該值指示是否可指定篩選器特性的多個(gè)實(shí)例。 // 返回結(jié)果:如果可指定篩選器特性的多個(gè)實(shí)例,則為 true;否則為 false。 public bool AllowMultiple { get; } // 摘要: 獲取或者設(shè)置執(zhí)行操作篩選器的順序。 // 返回結(jié)果:執(zhí)行操作篩選器的順序。 public int Order { get; set; } } }
內(nèi)建過(guò)濾器
過(guò)濾器 | 描述 |
RequireHttps | 強(qiáng)迫Action使用Https協(xié)議 |
OutputCache | 緩存一個(gè)Action的 |
ValidateInputand ValidationAntiForgeryToken | 與安全性有關(guān)的授權(quán)過(guò)濾器 |
AsyncTimeout NoAsyncTimeout | 用戶(hù)異步控制器 |
ChildActionOnlyAttribute | 一個(gè)支持Html.action和Html.RenderAction輔助器方法的過(guò)濾器 |
RequireHttps
RequireHttps過(guò)濾器讓Action強(qiáng)制使用HTTPS協(xié)議。他將用戶(hù)瀏覽器重定向到同一個(gè)動(dòng)作,但使用‘https://'協(xié)議前綴
在形成不安全請(qǐng)求時(shí),重寫(xiě)HandledNonHttpsRequest(),以創(chuàng)建自定義行為,該過(guò)濾器僅用于GET請(qǐng)求,POST則會(huì)丟掉數(shù)據(jù);該過(guò)濾器時(shí)授權(quán)過(guò)濾器
關(guān)于如何在ASP.NET mvc4項(xiàng)目中使用過(guò)濾器就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。