國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
前言:什麼是 ActionFilterAttribute?
ActionFilterAttribute 是一種作用於控制器 Action 方法的特性(Attribute),通過它,你可以在操作執行前後、異常處理時等不同的階段插入自定義邏輯。
比如在執行操作方法之前修改請求參數、記錄日誌、進行許可權驗證等操作,在執行操作方法之後發送郵件、同步數據等等。
本文主要通過一些例子來說明什麼是 ActionFilterAttribute 及如何應用。
Step By Step 步驟:
-
創建一個 asp.net core webapi 的項目
-
直接繼承
ActionFilterAttribute
抽象類創建自定義的Test1ActionFilterAttribute
類並註入 ILoggerusing Microsoft.AspNetCore.Mvc.Filters; namespace AttributeSample { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class Test1ActionFilterAttribute: ActionFilterAttribute { private ILogger<Test1ActionFilterAttribute> _logger; // 在構造方法里註入 ILogger public Test1ActionFilterAttribute(ILogger<Test1ActionFilterAttribute> logger) { _logger = logger; } /// <summary> /// 在控制器執行之前調用 /// </summary> /// <param name="context"></param> public override void OnActionExecuting(ActionExecutingContext context) { _logger.LogInformation("在控制器執行之前調用..."); base.OnActionExecuting(context); } /// <summary> /// 在控制器執行之後調用 /// </summary> /// <param name="context"></param> public override void OnActionExecuted(ActionExecutedContext context) { _logger.LogInformation("在控制器執行之後調用..."); base.OnActionExecuted(context); } } }
-
通過實現
IActionFilter
介面創建自定義的Test2ActionFilterAttribute
類並註入 ILogger(推薦方式)using Microsoft.AspNetCore.Mvc.Filters; namespace AttributeSample { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class Test2ActionFilterAttribute: Attribute, IActionFilter { private ILogger<Test2ActionFilterAttribute> _logger; // 在構造方法里註入 ILogger public Test2ActionFilterAttribute(ILogger<Test2ActionFilterAttribute> logger) { _logger = logger; } /// <summary> /// 在控制器執行之前調用 /// </summary> /// <param name="context"></param> public void OnActionExecuting(ActionExecutingContext context) { _logger.LogInformation("在控制器執行之前調用..."); } /// <summary> /// 在控制器執行之後調用 /// </summary> /// <param name="context"></param> public void OnActionExecuted(ActionExecutedContext context) { _logger.LogInformation("在控制器執行之後調用..."); } } }
-
直接繼承
ActionFilterAttribute
抽象類創建自定義的Test3ActionFilterAttribute
類,不註入其他依賴using Microsoft.AspNetCore.Mvc.Filters; namespace AttributeSample { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class Test3ActionFilterAttribute: Attribute, IActionFilter { private string _myName; public Test3ActionFilterAttribute(string myName) { _myName = myName; } /// <summary> /// 在控制器執行之前調用 /// </summary> /// <param name="context"></param> public void OnActionExecuting(ActionExecutingContext context) { _myName += " before"; } /// <summary> /// 在控制器執行之後調用 /// </summary> /// <param name="context"></param> public void OnActionExecuted(ActionExecutedContext context) { _myName += " after"; } } }
-
在控制器中應用自定義的
ActionFilterAttribute
using Microsoft.AspNetCore.Mvc; using AttributeSample; using System.Reflection; namespace AttributeSample.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger<WeatherForecastController> _logger; /// <summary> /// /// </summary> /// <param name="logger"></param> public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet(Name = "GetWeatherForecast")] [TypeFilter(typeof(Test1ActionFilterAttribute))] [TypeFilter(typeof(Test2ActionFilterAttribute))] [Test3ActionFilter("Jacky")] public IEnumerable<WeatherForecast> Get() { var list = Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); _logger.LogInformation("執行方法..."); return list; } } }
-
在
Swaager
測試,可以看到其執行順序如下:AttributeSample.Test1ActionFilterAttribute: Information: 在控制器執行之前調用... AttributeSample.Test2ActionFilterAttribute: Information: 在控制器執行之前調用... AttributeSample.Test3ActionFilterAttribute... AttributeSample.Controllers.WeatherForecastController: Information: 執行方法... AttributeSample.Test3ActionFilterAttribute... AttributeSample.Test2ActionFilterAttribute: Information: 在控制器執行之後調用... AttributeSample.Test1ActionFilterAttribute: Information: 在控制器執行之後調用...
總結:
- Asp.net core webapi 使用 ActionFilterAttribute,引用的是 Microsoft.AspNetCore.Mvc.Filters 而不是 System.Web.Http.Filters
- System.Web.Http.Filters 是屬於 .Net FrameWork 的命名空間
- ActionFilterAttribute 如果需要在構造方法中註入某些依賴,比如註入 ILogger,有幾個使用方法:
- TypeFilter,無需在IOC中註冊,有自實現,本文例子即是使用這種方式
- ServiceFilter,需要在 Program.cs 中針對該過濾器註冊服務才能使用
- 自定義 CustomIOCFilterFactoryAttribute 實現,依然需要對過濾器進行服務註冊
- 方法2和3比較複雜,以後有時間再針對這兩種方式寫一些例子
- 沒有註入其他依賴的 ActionFilterAttribute 如一般 Attribute 使用即可,比如本文的第 3 個 ActionFilterAttribute
- [Test3ActionFilter("Jacky")]
我是老楊,一個執著於編程樂趣、至今奮鬥在一線的 10年+ 資深研發老鳥,是軟體項目管理師,也是快樂的程式猿,持續免費分享全棧實用編程技巧、項目管理經驗和職場成長心得!歡迎關註老楊的公眾號(名稱:代碼掌控者),和你共同探索代碼世界的奧秘!