.NET 6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)ActionFilter
需求
Filter在.NET Web API項(xiàng)目開發(fā)中也是很重要的一個(gè)概念,它運(yùn)行在執(zhí)行MVC響應(yīng)的Pipeline中執(zhí)行,允許我們將一些可以在多個(gè)Action之間重用的邏輯抽取出來(lái)集中管理。雖然我們?cè)谏弦黄褂?a href="http://www.dhdzp.com/article/233278.htm" target="_blank">.NET 6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)接口請(qǐng)求驗(yàn)證中演示了如何通過(guò)使用MediatR提供的IPipelineBehavior接口在CQRS的Handle方法執(zhí)行前后插入可重用代碼,而本文所演示的Filters作用在Controller的Action執(zhí)行或Action返回結(jié)果前后。
可以創(chuàng)建自定義Filters,用于處理應(yīng)用程序中的橫切片關(guān)注點(diǎn)。 橫切片關(guān)注點(diǎn)的包括錯(cuò)誤處理、緩存、配置、授權(quán)和日志記錄。 Filters可以避免重復(fù)代碼。
Filter的類型分為以下幾種:
Authorization Filters:最先運(yùn)行,用于確定是否已針對(duì)請(qǐng)求為用戶授權(quán)。 如果請(qǐng)求未獲授權(quán),Authorization Filters可以讓管道短路。
Resource Filters:授權(quán)后運(yùn)行。OnResourceExecuting在Filter Pipeline的其余階段之前運(yùn)行代碼。OnResourceExecuted在管道的其余階段完成之后運(yùn)行代碼??梢杂眠@個(gè)類型的Filter進(jìn)行緩存和性能統(tǒng)計(jì)。
Action Filters:在調(diào)用操作方法之前和之后立即運(yùn)行代碼。它可以更改傳遞到操作中的參數(shù),也可以更改從操作返回的結(jié)果,當(dāng)然如果什么都不更改僅作記錄也是可以的。
Exception Filters:在向響應(yīng)正文寫入任何內(nèi)容之前,對(duì)未經(jīng)處理的異常應(yīng)用全局策略。
Result Filters:在執(zhí)行操作結(jié)果返回之前和之后運(yùn)行代碼。 僅當(dāng)操作方法成功執(zhí)行時(shí),它們才會(huì)被運(yùn)行。
這五種Filters在Filter Pipeline中直觀的展現(xiàn)是這樣的:

而整個(gè)FIlter Pipeline在完整的Middleware Pipeline中的階段是這樣的:

在本文中,我們將演示Action Filters是如何在Controller的Action執(zhí)行前后記錄請(qǐng)求和響應(yīng)日志的。
目標(biāo)
使用Action Filters進(jìn)行接口日志記錄。
原理與思路
創(chuàng)建一個(gè)自定義的Action Filter,用于實(shí)現(xiàn)Controller的接口日志邏輯。
實(shí)現(xiàn)
在Api新建文件夾Filters并創(chuàng)建類LogFilterAttribute:
LogFilterAttribute.cs
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace TodoList.Api.Filters;
public class LogFilterAttribute : IActionFilter
{
private readonly ILogger<LogFilterAttribute> _logger;
public LogFilterAttribute(ILogger<LogFilterAttribute> logger) => _logger = logger;
public void OnActionExecuting(ActionExecutingContext context)
{
var action = context.RouteData.Values["action"];
var controller = context.RouteData.Values["controller"];
// 獲取名稱包含Command的參數(shù)值
var param = context.ActionArguments.SingleOrDefault(x => x.Value.ToString().Contains("Command")).Value;
_logger.LogInformation($"Controller:{controller}, action: {action}, Incoming request: {JsonSerializer.Serialize(param)}");
}
public void OnActionExecuted(ActionExecutedContext context)
{
var action = context.RouteData.Values["action"];
var controller = context.RouteData.Values["controller"];
// 需要先將Result轉(zhuǎn)換為ObjectResult類型才能拿到Value值
var result = (ObjectResult)context.Result!;
_logger.LogInformation($"Controller:{controller}, action: {action}, Executing response: {JsonSerializer.Serialize(result.Value)}");
}
}
依賴注入:
Program.cs
builder.Services.AddScoped<LogFilterAttribute>();
在需要應(yīng)用該Filter的Controller Action上添加屬性:
TodoListController.cs
[HttpPost]
[ServiceFilter(typeof(LogFilterAttribute))]
public async Task<ApiResponse<Domain.Entities.TodoList>> Create([FromBody] CreateTodoListCommand command)
{
return ApiResponse<Domain.Entities.TodoList>.Success(await _mediator.Send(command));
}
驗(yàn)證
啟動(dòng)Api項(xiàng)目,執(zhí)行創(chuàng)建TodoList的請(qǐng)求:
請(qǐng)求

響應(yīng)
來(lái)自于OnActionExecuting的請(qǐng)求數(shù)據(jù)日志:

注意在我們上一篇文章中的Handling CreateTodoListCommand之前輸出的內(nèi)容。
以及來(lái)自于OnActionExecuted輸出的返回?cái)?shù)據(jù)日志:

總結(jié)
在本文中我們通過(guò)一個(gè)很簡(jiǎn)單的例子,演示了Action Filter的基本用法。至此我們關(guān)于請(qǐng)求中間件管道的討論先告一個(gè)段落,后面說(shuō)到認(rèn)證鑒權(quán)的時(shí)候我們還會(huì)回來(lái)討論這個(gè)主題。?
到此這篇關(guān)于.NET 6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)ActionFilter的文章就介紹到這了,更多相關(guān).NET 6實(shí)現(xiàn)ActionFilter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- .NET 6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)查詢分頁(yè)
- .NET 6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)接口請(qǐng)求驗(yàn)證
- .NET?6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)DELETE請(qǐng)求與HTTP請(qǐng)求冪等性
- .NET 6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)PUT請(qǐng)求
- .NET 6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)全局異常處理
- .NET 6開發(fā)TodoList應(yīng)用之使用AutoMapper實(shí)現(xiàn)GET請(qǐng)求
- .NET?6開發(fā)TodoList應(yīng)用之實(shí)現(xiàn)Repository模式
- .NET?6開發(fā)TodoList應(yīng)用之使用MediatR實(shí)現(xiàn)POST請(qǐng)求
- .NET 6開發(fā)TodoList應(yīng)用引入數(shù)據(jù)存儲(chǔ)
- .NET?6開發(fā)TodoList應(yīng)用引入第三方日志庫(kù)
- .NET 6開發(fā)TodoList應(yīng)用實(shí)現(xiàn)結(jié)構(gòu)搭建
- .NET?6開發(fā)TodoList應(yīng)用實(shí)現(xiàn)系列背景
- 使用.NET?6開發(fā)TodoList應(yīng)用之引入數(shù)據(jù)存儲(chǔ)的思路詳解
- 使用.NET?6開發(fā)TodoList應(yīng)用之領(lǐng)域?qū)嶓w創(chuàng)建原理和思路
- .NET?6開發(fā)TodoList應(yīng)用之請(qǐng)求日志組件HttpLogging介紹
相關(guān)文章
jQuery調(diào)用WebService返回JSON數(shù)據(jù)及參數(shù)設(shè)置注意問(wèn)題
.NET Framework 3.5的發(fā)布解決了WebService調(diào)用中json問(wèn)題,本文將介紹jQuery調(diào)用基于.NET Framework 3.5的WebService返回JSON數(shù)據(jù),感興趣的朋友可以了解下,希望本文對(duì)你有所幫助2013-01-01
asp.net core實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了asp.net core實(shí)現(xiàn)文件上傳功能,怎么做單文件和多文件上傳,感興趣的小伙伴們可以參考一下2016-06-06
基于.NET中:自動(dòng)將請(qǐng)求參數(shù)綁定到ASPX、ASHX和MVC的方法(菜鳥必看)
這篇文章的目的就是告訴初學(xué)者如何自動(dòng)將客戶端用AJAX發(fā)送的參數(shù)自動(dòng)綁定為強(qiáng)類型的成員屬性或方法參數(shù)2013-04-04
ajaxToolkit:AccordionPane演示與應(yīng)用實(shí)例
ajaxToolkit:AccordionPane演示與應(yīng)用實(shí)例,需要的朋友可以參考一下2013-04-04
ASP.NET?Core中MVC模式實(shí)現(xiàn)路由一
這篇文章介紹了ASP.NET?Core中MVC模式實(shí)現(xiàn)路由的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
.net設(shè)計(jì)模式之裝飾模式(Decorator)
這篇文章主要為大家詳細(xì)介紹了.net設(shè)計(jì)模式之裝飾模式Decorator,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06

