隨著技術的發(fā)展,ASP.NET Core MVC也推出了好長時間,經(jīng)過不斷的版本更新迭代,已經(jīng)越來越完善,本系列文章主要講解ASP.NET Core MVC開發(fā)B/S系統(tǒng)過程中所涉及到的相關內(nèi)容,適用于初學者,在校畢業(yè)生,或其他想從事ASP.NET Core MVC 系統(tǒng)開發(fā)的人員。
經(jīng)過前幾篇文章的講解,初步了解ASP.NET Core MVC項目創(chuàng)建,啟動運行,以及命名約定,創(chuàng)建控制器,視圖,模型,接收參數(shù),傳遞數(shù)據(jù)ViewData,ViewBag,路由,頁面布局,wwwroot和客戶端庫,Razor語法,EnityFrameworkCore與數(shù)據(jù)庫,HttpContext,Request,Response,Session,序列化,文件上傳,自動映射,Html輔助標簽,模型校驗,鑒權、授權基礎,Identity入門,日志管理等內(nèi)容,今天繼續(xù)講解ASP.NET Core MVC 中Filter(篩選器)等相關內(nèi)容,僅供學習分享使用。
什么是Filter?
Filter又稱為篩選器,過濾器。在ASP.NET Core MVC項目中,通過使用Filter,可以在請求處理管道的特定位置之前或之后運行代碼??梢詣?chuàng)建自定義Filter,用于處理橫切關注點,類似于AOP面向切面編程。對于創(chuàng)建Filter,可以減少代碼的復制,例如,錯誤處理異常篩選器可以合并錯誤處理。
Filter工作原理
從請求開始,到請求結束,經(jīng)過一系列的節(jié)點,組成了調(diào)用管道。Filter在ASP.NET Core MVC的調(diào)用管道內(nèi)運行,過濾器相當于在管道中設置的幾個鉤子,用于執(zhí)行特定的代碼。
Filter類型
根據(jù)不同的處理功能,篩選器主要分為以下幾類:
-
授權篩選器AuthorizationFilter:
- 首先運行。
- 確定用戶是否獲得請求授權。
- 如果請求未獲授權,可以讓管道短路。
-
資源篩選器Resource Filter:
- 授權后運行。
- OnResourceExecuting?在篩選器管道的其余階段之前運行代碼。 例如,
OnResourceExecuting
?在模型綁定之前運行代碼。 - OnResourceExecuted?在管道的其余階段完成之后運行代碼。
-
操作篩選器Action Filter:
- 在調(diào)用操作方法之前和之后立即運行。
- 可以更改傳遞到操作中的參數(shù)。
- 可以更改從操作返回的結果。
- 不可在 Razor Pages 中使用。
-
異常篩選器Exception Filter:在向響應正文寫入任何內(nèi)容之前,對未經(jīng)處理的異常應用全局策略。
-
結果篩選器Result Filter:
- 在執(zhí)行操作結果之前和之后立即運行。
- 僅當操作方法成功執(zhí)行時才會運行。
- 對于必須圍繞視圖或格式化程序的執(zhí)行的邏輯,會很有用。
?下圖展示了Filter篩選器類型在篩選器管道中的交互方式:
Filter實現(xiàn)
所有的Filter都實現(xiàn)接口IFilterMetadata,根據(jù)不同的業(yè)務類型,派生出了五個接口,分別對應五大類Filter,如下所示:
注意:上述五個接口還有對應異步接口(Async)。
?Filter作用域
Filter可以作用在Controller,Action,全局。下面的示例闡釋了為同步操作篩選器運行篩選器方法的順序:
?
?
授權Filter
授權篩選器:
- 是篩選器管道中運行的第一個篩選器。
- 控制對操作方法的訪問。
- 具有在它之前的執(zhí)行的方法,但沒有之后執(zhí)行的方法。
如常用的RequireHttps就是授權篩選器,它實現(xiàn)了IAuthorizationFilter接口,并繼承了Attirbute,所以可以作用于Controller或Action中。以限制請求的方式。
1 using Microsoft.AspNetCore.Mvc.Filters; 2 using System; 3 4 namespace Microsoft.AspNetCore.Mvc 5 { 6 // 7 // 摘要: 8 // An authorization filter that confirms requests are received over HTTPS. 9 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 10 public class RequireHttpsAttribute : Attribute, IAuthorizationFilter, IFilterMetadata, IOrderedFilter 11 { 12 public RequireHttpsAttribute(); 13 14 // 15 // 摘要: 16 // Specifies whether a permanent redirect, 301 Moved Permanently, should be used 17 // instead of a temporary redirect, 302 Found. 18 public bool Permanent { get; set; } 19 // 20 // 值: 21 // Default is int.MinValue + 50 to run this Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter 22 // early. 23 public int Order { get; set; } 24 25 // 26 // 摘要: 27 // Called early in the filter pipeline to confirm request is authorized. Confirms 28 // requests are received over HTTPS. Takes no action for HTTPS requests. Otherwise 29 // if it was a GET request, sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result 30 // to a result which will redirect the client to the HTTPS version of the request 31 // URI. Otherwise, sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result 32 // to a result which will set the status code to 403 (Forbidden). 33 public virtual void OnAuthorization(AuthorizationFilterContext filterContext); 34 // 35 // 摘要: 36 // Called from Microsoft.AspNetCore.Mvc.RequireHttpsAttribute.OnAuthorization(Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext) 37 // if the request is not received over HTTPS. Expectation is Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result 38 // will not be null after this method returns. 39 // 40 // 參數(shù): 41 // filterContext: 42 // The Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext to update. 43 // 44 // 言論: 45 // If it was a GET request, default implementation sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result 46 // to a result which will redirect the client to the HTTPS version of the request 47 // URI. Otherwise, default implementation sets Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext.Result 48 // to a result which will set the status code to 403 (Forbidden). 49 protected virtual void HandleNonHttpsRequest(AuthorizationFilterContext filterContext); 50 } 51 }
?
資源Filter
資源Filter在授權Filter之后執(zhí)行,需要實現(xiàn)IResourceFilter接口。如下所示:
1 using Microsoft.AspNetCore.Mvc.Filters; 2 3 namespace DemoCoreMVC.Filter 4 { 5 /// <summary> 6 /// 同步版本 7 /// </summary> 8 public class LogResourceFilter :Attribute, IResourceFilter 9 { 10 public void OnResourceExecuted(ResourceExecutedContext context) 11 { 12 //Action執(zhí)行完成后執(zhí)行 13 Console.WriteLine("********************On Resource Filter Executed********************"); 14 } 15 16 public void OnResourceExecuting(ResourceExecutingContext context) 17 { 18 //授權Filter執(zhí)行后執(zhí)行。 19 Console.WriteLine("********************On Resource Filter Executing********************"); 20 } 21 } 22 23 /// <summary> 24 /// 異步版本 25 /// </summary> 26 public class AsynLogResouceFilter : Attribute, IAsyncResourceFilter 27 { 28 public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) 29 { 30 Console.WriteLine("********************On Aysnc Resource Filter Executing********************"); 31 var exceutedContext = await next(); 32 Console.WriteLine("********************On Async Resource Filter Executed********************"); 33 } 34 } 35 }
如果要使大部分管道短路,資源篩選器會很有用。 例如,如果緩存命中,則緩存篩選器可以繞開管道的其余階段。
操作Filter
操作篩選器不應用于 Razor Pages。 Razor Pages 支持?IPageFilter?和?IAsyncPageFilter。
操作篩選器:
- 實現(xiàn)?IActionFilter?或?IAsyncActionFilter?接口。
- 它們的執(zhí)行圍繞著操作方法的執(zhí)行。
以下代碼顯示示例操作篩選器:
1 using Microsoft.AspNetCore.Mvc.Filters; 2 3 namespace DemoCoreMVC.Filter 4 { 5 public class DoDoActionFilter : Attribute, IActionFilter 6 { 7 public void OnActionExecuted(ActionExecutedContext context) 8 { 9 10 Console.WriteLine("********************On Action Executed********************"); 11 } 12 13 public void OnActionExecuting(ActionExecutingContext context) 14 { 15 Console.WriteLine("********************On Action Executing********************"); 16 } 17 } 18 19 public class AsyncDoDoActionFilter : IAsyncActionFilter 20 { 21 public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 22 { 23 24 Console.WriteLine("********************On Async Action Executing********************"); 25 await next(); 26 Console.WriteLine("********************On Async Action Executed********************"); 27 } 28 } 29 }
?
ActionExecutingContext?提供以下屬性:
- ActionArguments?- 用于讀取操作方法的輸入。
- Controller?- 用于處理控制器實例。
- Result?- 設置?
Result
?會使操作方法和后續(xù)操作篩選器的執(zhí)行短路。
ActionExecutedContext?提供?Controller
?和?Result
?以及以下屬性:
- Canceled?- 如果操作執(zhí)行已被另一個篩選器設置短路,則為 true。
- Exception?- 如果操作或之前運行的操作篩選器引發(fā)了異常,則為非 NULL 值。 將此屬性設置為 null:
- 有效地處理異常。
- 執(zhí)行?
Result
,從操作方法中將它返回。
對于?IAsyncActionFilter
,一個向?ActionExecutionDelegate?的調(diào)用可以達到以下目的:
- 執(zhí)行所有后續(xù)操作篩選器和操作方法。
- 返回?
ActionExecutedContext
。
異常Filter
異常篩選器:
- 實現(xiàn)?IExceptionFilter?或?IAsyncExceptionFilter。
- 可用于實現(xiàn)常見的錯誤處理策略。
下面的異常篩選器示例顯示在開發(fā)應用時發(fā)生的異常的相關詳細信息:
1 using Microsoft.AspNetCore.Mvc.Filters; 2 3 namespace DemoCoreMVC.Filter 4 { 5 public class DoExceptionFilter :Attribute, IExceptionFilter 6 { 7 public void OnException(ExceptionContext context) 8 { 9 Console.WriteLine("********************On Exception********************"); 10 } 11 } 12 13 public class DoAsyncExceptionFilter : Attribute, IAsyncExceptionFilter 14 { 15 public async Task OnExceptionAsync(ExceptionContext context) 16 { 17 await Task.Run(() => 18 { 19 Console.WriteLine("********************On Exception Async********************"); 20 }); 21 22 } 23 } 24 }
異常篩選器:
- 沒有之前和之后的事件。
- 實現(xiàn)?OnException?或?OnExceptionAsync。
- 處理 Razor 頁面或控制器創(chuàng)建、模型綁定、操作篩選器或操作方法中發(fā)生的未經(jīng)處理的異常。
- 請不要捕獲資源篩選器、結果篩選器或 MVC 結果執(zhí)行中發(fā)生的異常。
若要處理異常,請將?ExceptionHandled?屬性設置為?true
?或分配?Result?屬性。 這將停止傳播異常。 異常篩選器無法將異常轉變?yōu)椤俺晒Α薄?只有操作篩選器才能執(zhí)行該轉變。
異常篩選器:
- 非常適合捕獲發(fā)生在操作中的異常。
- 并不像錯誤處理中間件那么靈活。
建議使用中間件處理異常。 基于所調(diào)用的操作方法,僅當錯誤處理不同時,才使用異常篩選器。 例如,應用可能具有用于 API 終結點和視圖/HTML 的操作方法。 API 終結點可以將錯誤信息返回為 JSON,而基于視圖的操作可能會以 HTML 形式返回錯誤頁。
結果Filter
結果篩選器:
- 實現(xiàn)接口:
- IResultFilter?或?IAsyncResultFilter
- IAlwaysRunResultFilter?或?IAsyncAlwaysRunResultFilter
- 它們的執(zhí)行圍繞著操作結果的執(zhí)行。
1 using Microsoft.AspNetCore.Mvc.Filters; 2 3 namespace DemoCoreMVC.Filter 4 { 5 public class DoResultFilter :Attribute, IResultFilter 6 { 7 public void OnResultExecuted(ResultExecutedContext context) 8 { 9 Console.WriteLine("********************On Result Executed********************"); 10 } 11 12 public void OnResultExecuting(ResultExecutingContext context) 13 { 14 Console.WriteLine("********************On Result Executing********************"); 15 } 16 } 17 18 public class DoAysncResultFilter :Attribute, IAsyncResultFilter 19 { 20 public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next) 21 { 22 Console.WriteLine("********************On Result Execution Async Executing********************"); 23 await next(); 24 Console.WriteLine("********************On Result Execution Async Executed********************"); 25 } 26 } 27 28 }
Filter測試
將寫好的過濾器,放在Home/Index上,如下所示:
1 [DoExceptionFilter] 2 [LogResourceFilter] 3 [DoResultFilter] 4 [DoDoActionFilter] 5 public IActionResult Index() 6 { 7 _logger.LogInformation("Hello, 這是首頁!"); 8 return View(); 9 }
測試如下所示:
說明:異常過濾器沒有輸出內(nèi)容,是因為沒有異常產(chǎn)生。授權過濾器沒有添加,在所有過濾器之前開始,所有過濾器之后結束。
Filter全局應用
Filter可以應用在單個Controller或Action上,也可以進行全局應用,代碼如下所示:
1 builder.Services.AddControllersWithViews(option => 2 { 3 option.Filters.Add<LogResourceFilter>(); 4 option.Filters.Add<DoExceptionFilter>(); 5 option.Filters.Add<DoResultFilter>(); 6 option.Filters.Add<DoDoActionFilter>(); 7 });
全局測試如下所示:
以上就是ASP.NET Core MVC 從入門到精通之Filter的全部內(nèi)容。文章來源:http://www.zghlxwxcb.cn/news/detail-494004.html
參考文檔
官方文檔:https://learn.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-6.0文章來源地址http://www.zghlxwxcb.cn/news/detail-494004.html
到了這里,關于ASP.NET Core MVC 從入門到精通之Filter的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!