.NET 8 - ASP.NET Core Web API Filters

ActionFilter, NET8,

引言

懶~

參考文件

開發環境

平台: NET8 骨架: ASP.NET Core Web API IDE: Visual Studio 2022

關鍵知識

在 NET8 Filter 的套用方式有二種: 一、在 Program 註冊該 Filter, 將會套用到全部 Controls\Actions。 二、在該 Action 手動一個個指定,只在該 Action 有效。

關鍵程式碼紀錄

定義 Filter

目的一:用於追縱全部 Controls\Actions

Filters\WebApiTracker.cs
using Microsoft.AspNetCore.Mvc.Filters;
namespace YourWebAPI.Filters;

public class WebApiTracker(ILogger<WebApiTracker> _logger) : IActionFilter
{
  void IActionFilter.OnActionExecuting(ActionExecutingContext context)
  {
    var displayName = context.ActionDescriptor.DisplayName;
    _logger.LogTrace($"{displayName} : BEGIN");
  }

  void IActionFilter.OnActionExecuted(ActionExecutedContext context)
  {
    var displayName = context.ActionDescriptor.DisplayName;
    if (context.Exception != null)
      _logger.LogCritical($"{displayName} => Exception! {context.Exception.Message}");
    else
      _logger.LogTrace($"{displayName} : DONE");
  }
}

在 Program.cs 註冊

Program.cs
var builder = WebApplication.CreateBuilder(args);
  
// Add services to the container. 
builder.Services.AddControllers(options => { 
  options.Filters.Add<WebApiTracker>(); //※此Filter 將會套用到全部 WebAPI。
});
...略...

目的二:用於 CatchAndLog 把未處理的 500 Exception 轉成已處理的 400 Exception。

將一一指定,故不用在 Program.cs 註冊。

Filters\CatchAndLog.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Serilog;
namespace YourWebAPI.Filters;

public class CatchAndLog(string title) : Attribute, IActionFilter
{
  void IActionFilter.OnActionExecuting(ActionExecutingContext context)
  {
    Log.Debug($"{title} : BEGIN");
  }

  void IActionFilter.OnActionExecuted(ActionExecutedContext context)
  {
    //# SUCCESS
    if (context.Exception == null)
    {
      Log.Information($"{title} : DONE");
      return;
    }

    //# FAIL
    Log.Error($"{title} => Exception! {context.Exception.Message}");

    // Excepiton => 40
    context.Result = new ContentResult
    {
      StatusCode = 400,
      Content = context.Exception.Message
    };

    //※ 需設定此例外已處理,否則後序會再處理例外。
    context.ExceptionHandled = true;
  }
}

套用到目標 Control\Action。

Controllers\SampleController.cs
using Microsoft.AspNetCore.Mvc;
namespace YourWebAPI.Controllers;

[ApiController]
[Route("[controller]")]
public class SampleController(...略...) : ControllerBase
{
  [HttpPost("[action]")]
  [CatchAndLog("取得天氣預報資料")] //<--- ※指定 ActionFilter。
  public IEnumerable<WeatherForecast> GetWeatherForecast(int count = 3)
  {
    ...略...
  }
}

(EOF)

Last updated