Middleware vs Filter:什麼時候用哪個?
執行順序
HTTP Request 進來
↓
Middleware 1(最外層)
↓
Middleware 2
↓
Middleware 3(路由、認證、授權...)
↓
[進入 MVC 管線]
↓
Authorization Filter
↓
Resource Filter(Before)
↓
Action Filter(Before)
↓
Controller Action 執行
↓
Action Filter(After)
↓
Result Filter
↓
Resource Filter(After)
↓
[離開 MVC 管線]
↓
Middleware 3, 2, 1(反向回程)
↓
HTTP Response 出去
關鍵差異
| Middleware | Filter | |
|---|---|---|
| 作用範圍 | 所有 Request(包含靜態檔案) | 只有 MVC/API Action |
| 能存取什麼 | HttpContext | ActionContext、ModelState、ActionArguments |
| 適合做什麼 | 日誌、CORS、壓縮、認證 | 驗證、授權、快取、例外處理 |
| 可以短路嗎 | ✅ 不呼叫 next() | ✅ 設定 Result |
| 執行順序控制 | 註冊順序決定 | 可以設定 Order |
| 可以用 DI 嗎 | 建構函式注入 | 支援(用 ServiceFilter) |
選擇指南
要處理所有 HTTP 請求? → Middleware
例:全域日誌、CORS、Response 壓縮、速率限制
只處理 MVC Action? → Filter
例:模型驗證、授權檢查、Action 計時
需要存取 ModelState? → Filter
需要存取 ActionArguments? → Filter
需要在路由之前執行? → Middleware
實際案例
// Middleware:記錄每個 Request 的時間(包含靜態檔案)
app.Use(async (context, next) => {
var sw = Stopwatch.StartNew();
await next();
Console.WriteLine($"{context.Request.Path} took {sw.ElapsedMilliseconds}ms");
});
// Filter:檢查 Action 的模型是否有效
public class ValidateModelFilter : IActionFilter {
public void OnActionExecuting(ActionExecutingContext context) {
if (!context.ModelState.IsValid)
context.Result = new BadRequestObjectResult(context.ModelState);
}
public void OnActionExecuted(ActionExecutedContext context) { }
}
簡單記法:Middleware 管 HTTP 層面,Filter 管 MVC 層面。