以往,在.NET Framework時代,有Message Handller的方式,可以透過PipeLine,逐層處理Request與Response
現在,走進.NET(Core)的WebAPI,找到類似的機制,但目前討論的不多,所以做個紀錄
緣起
以往,在.NET Framework時代,有Message Handler的方式,可以透過PipeLine,逐層處理Request與Response
現在,走進.NET(Core)的WebAPI,找到類似的機制,但目前討論的不多,所以做個紀錄。
回顧Message Handler
過往,我們會透過Message Handler,在Client的Request還沒進入Controller之前,把一些放在Header中的東西,預先處理(驗證、轉換、後製、...),然後將處理後的資訊,補充在Header中,繼續往下傳。或者在Response的過程中,一些共同要處理的,也可以在Message Handler中層層處理過後,再持續往外傳。這樣的機制小喵覺得還蠻好用的,每一層的任務也可以單一單純。

Custom Middleware
現在小喵終於有機會要轉到.NET開始了,之前好用的 Message Handler就要找替代方案,幾經尋找(感謝AI的幫忙),終於找到類似的機制,這就是這一篇的主題【Custom Middlerware】。
一樣會有PipeLine的運作,一樣可以處理Request與Response非同步的處理。而這部分,其實官方的範本已經寫得很不錯,請參考:
撰寫自訂的 ASP.NET Core 中介軟體
https://learn.microsoft.com/zh-tw/aspnet/core/fundamentals/middleware/write?view=aspnetcore-8.0
小喵的需求,是希望在Header中,加上一個ApiToken的資料作為驗證機制,這個ApiToken,呼叫端與我這邊,會有共同的邏輯,每隔一段時間會切換,用以鎖定只有合法ApiToken的Request才能合法繼續進入,否則就退回
相關的範例如下:
建立Custom Middleware類別
using System.Globalization;
namespace PTCMAPI.Models.MWs
{
public class RequestApiTokenMiddleware
{
private readonly RequestDelegate _next;
public RequestApiTokenMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Headers.TryGetValue("ApiToken", out var apiToken))
{
// Validate the API token
if (!IsValidApiToken(apiToken))
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsync("ApiToken不正確");
return;
}
}
else
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("無法取得ApiToken");
return;
}
await _next(context);
}
private bool IsValidApiToken(string apiToken)
{
// 驗證ApiToken邏輯在此,請自行修改合適的邏輯,這邊以固定的內容作示範
return apiToken == "9F7BD0138AF743E3980A8FFACD38F8C7";
}
}
public static class RequestApiTokenMiddlewareExtensions
{
public static IApplicationBuilder UseRequestApiToken(this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestApiTokenMiddleware>();
}
}
}
在Program.cs中使用
在適當的位置,加入以下這句
app.UseRequestApiToken();
這樣,就處理好一層的Custom Middleware
同場加映:在Swagger中增加輸入ApiToken
.NET 8的WebAPI專案建立過程中,可以順便加上Swagger,來提供WebAPI的說明與測試。既然已經在WebAPI加上ApiToken的驗證,那麼在Swagger中,也應該加上一個ApiToken的輸入,讓在Swagger測試時,也可以隨時輸入該ApiToken,以利測試。相關作法如下:
步驟一:新增Swagger要用的AddCustomHeaderParameter類別
小喵在Models中的Swagger資料夾中,新增一個類別,命名為 AddCustomHeaderParameter
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace PTCMAPI.Models.Swagger
{
public class AddCustomHeaderParameter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
{
operation.Parameters = new List<OpenApiParameter>();
}
operation.Parameters.Add(new OpenApiParameter
{
Name = "ApiToken",
In = ParameterLocation.Header,
Required = true,
Schema = new OpenApiSchema
{
Type = "string"
}
});
}
}
}
步驟二:修改Program.cs
將 Program.cs 中,原本的 builder.Services.AddSwaggerGen(); 改為以下:
builder.Services.AddSwaggerGen(options =>
{
options.OperationFilter<AddCustomHeaderParameter>();
});
就醬子,Swagger中,輸入ApiToken的部分也做好了。
末記
從.NET Framework 轉換到 .NET的世界,有些東西還是陌生的,以往覺得好的東西,一點一滴地慢慢找回可以對應的機制,這次使用Custom Middleware來取代之前的Message Handler。提供改有需要的人參考,也順便紀錄一下,以免記性不好忘了。
以下是簽名:
- 歡迎轉貼本站的文章,不過請在貼文主旨上加上【轉貼】,並在文章中附上本篇的超連結與站名【topcat姍舞之間的極度凝聚】,感恩大家的配合。
- 小喵大部分的文章會以小喵熟悉的語言VB.NET撰寫,如果您需要C#的Code,也許您可以試著用線上的工具進行轉換,這裡提供幾個參考
Microsoft MVP Visual Studio and Development Technologies (2005~2019/6) | topcat Blog:http://www.dotblogs.com.tw/topcat |