CodeShot
Seniorسختی 4 از ۵· در 47٪ مصاحبه‌های این حوزه پرسیده شده

چه زمانی Middleware بنویسیم و چه زمانی Action Filter؟

نشان کردن

پاسخ کوتاه

Middleware برای منطق سطح کل برنامه و مستقل از MVC است؛ Filter وقتی به Model Binding، Action و ModelState دسترسی لازم داریم.

پاسخ کامل

Middleware در سطح HttpContext کار می‌کند و از وجود Controller و Action بی‌خبر است. برای لاگ‌گیری سراسری، فشرده‌سازی، مدیریت خطا، هدرهای امنیتی و Rate Limiting مناسب است.

Action Filter بعد از Routing و Model Binding اجرا می‌شود و به ActionArguments، ModelState و نتیجه Action دسترسی دارد. برای اعتبارسنجی مدل، کش کردن نتیجه یک Action خاص و Authorization وابسته به پارامترهای Action مناسب است.

قاعده عملی: اگر منطق شما به «کدام Action و با چه پارامترهایی» وابسته است، Filter بنویسید؛ در غیر این صورت Middleware.

مثال کد

public class CorrelationIdMiddleware
{
    private readonly RequestDelegate _next;
    public CorrelationIdMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext context)
    {
        context.Response.Headers["X-Correlation-Id"] = Guid.NewGuid().ToString();
        await _next(context);
    }
}

نکته مهم

Middleware یک‌بار ساخته می‌شود و در کل عمر برنامه زنده می‌ماند؛ بنابراین سرویس‌های Scoped را باید در InvokeAsync تزریق کنید، نه در سازنده.

اشتباه رایج

❌ تزریق DbContext در سازنده Middleware — این یک Captive Dependency است و در درخواست‌های هم‌زمان می‌شکند.