ASP.NET Core 5 EP 13:Middleware中介軟體實作
Middleware中介軟體
在ASP.NET Core中,以管線(Pipeline)的概念來處理要求(Request)與回應(Response)的軟體,Middleware可以說是門神,處理HTTP的”進”與”出”,重要的應用包含檢查HTTP Body格式、對HTTP Context添油加醋…等。
PS:Middleware的被執行順序,Request,在Filter之前,Response,在Filter之後。
既然Middleware具有管線(Pipeline)的概念,那當註冊多個Middleware時,就一定會有執行的先後順序,參考下圖,其實就是按照Request與Response的進與出。
建立一個Middleware來檢查HTTP Request Header
以下範例是檢查Request中的HTTP Request,是否帶有名為TEST這個Header,並檢查其內容為”12345″。
步驟1:在根資料夾建立一個Moddleware資料夾,並創建一個ReqHeaderChecker.cs的Class檔案。
步驟2:ReqHeaderChecker.cs內容如下:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace CookbookApi.Middleware
{
public class ReqHeaderChecker
{
private readonly RequestDelegate _next;
public ReqHeaderChecker(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
// 取得HTTP Request內的Headers
var headers = context.Request.Headers;
// 取得特定Header的內容
string header = headers["TEST"].ToString();
// 檢查Header的內容
if (!header.Equals(@"12345"))
{
throw new Exception("Header Error!");
}
// 將Request繼續往下送
await _next.Invoke(context);
}
}
}
步驟3:在Startup.cs檔案中全域註冊Middleware。
// ...
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
// 全域註冊剛剛撰寫用於檢查Header的Middleware
app.UseMiddleware<Middleware.ReqHeaderChecker>();
// ...
}
如何在Middleware中取得HTTP Body
若檢查或加工的對象不是Header,而是HTTP Body,可以參考以下語法:
StreamReader stream = new StreamReader(context.Request.Body);
string body = await stream.ReadToEndAsync();
註冊Middleware
全域註冊:如前面所提到,在Startup.cs中的Configure區域使用app.UseMiddleware方法即可簡單的全域註冊Middleware。
// ...
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
// 全域註冊剛剛撰寫用於檢查Header的Middleware
app.UseMiddleware<Middleware.ReqHeaderChecker>();
// ...
}
區域註冊:若只想要針對部分API,可以使用標注的方式,在Controller裡面的API方法上標註,以RecipeController.cs為例,我們指定Get()方法套用ReqHeaderChecker這個Middleware:
// 區域註冊Middleware
[MiddlewareFilter(typeof(Middleware.ReqHeaderChecker))]
// 設定這個API使用HEAD方法
[HttpHead]
// 設定這個API使用GET方法
[HttpGet]
public IActionResult Get()
{
// ...
}
~ END ~