ESC را فشار دهید تا بسته شود

زمیوس آموزش، یادگیری و سرگرمی

راهنمای کامل و بررسی انواع Filters در ASP.NET Core

مقدمه

اگر با فریم‌ورک ASP.NET Core کار کرده باشی، حتماً به این فکر افتادی که چطور می‌تونی بعضی منطق‌های تکراری مثل لاگ‌گیری، بررسی نقش کاربر، هندل کردن خطا یا حتی کش کردن پاسخ‌ها رو بدون نوشتن کد تکراری در همه‌ی اکشن‌ها پیاده‌سازی کنی.

اینجاست که فیلترها (Filters) در ASP.NET Core به کمکت میان!

در این مقاله آموزش دات نت کور به صورت کامل و جامع یاد می‌گیری:

  • فیلتر دقیقاً چیه و چرا بهش نیاز داریم؟
  • انواع فیلترها در ASP.NET Core
  • پیاده‌سازی و استفاده‌ی هر فیلتر با مثال واقعی
  • تفاوت‌ها، کاربردها و Best Practice ها

اگر می خواهید در با ویژگی‌های جدید NET 9. و ۱۳ #C در ِNetCore بیشتر آشنا بشید، نوشته زیر را مطالعه کنید:

در این نوشته شما می خوانید

فیلتر (Filter) در ASP.NET Core چیست؟

فیلترها کلاس‌هایی هستن که می‌تونی با کمک اون‌ها منطق‌های جانبی یا مقطعی رو در نقاط مختلف چرخه‌ی پردازش درخواست HTTP اجرا کنی. مثلاً:

  • قبل از اجرای اکشن
  • بعد از اجرای اکشن
  • قبل از تولید View
  • در صورت بروز خطا
  • حتی قبل از مدل بایندینگ!

📌 چرا فیلترها مهم هستند؟

چون به کمکشون می‌تونی:

  • از کدهای تکراری جلوگیری کنی
  • SOLID رو رعایت کنی
  • اپلیکیشنی تست‌پذیر و نگهدارپذیر بسازی

انواع فیلترها در ASP.NET Core

خلاصه انواع Filters:

نوع فیلتر اینترفیس‌های مرتبط زمان اجرا کاربرد رایج
Authorization Filter IAuthorizationFilter / IAsyncAuthorizationFilter قبل از مدل بایندینگ بررسی سطح دسترسی
Resource Filter IResourceFilter / IAsyncResourceFilter قبل از اکشن کش، تایمینگ
Action Filter IActionFilter / IAsyncActionFilter قبل و بعد از اکشن لاگ، اعتبارسنجی
Exception Filter IExceptionFilter / IAsyncExceptionFilter در زمان خطا مدیریت خطا
Result Filter IResultFilter / IAsyncResultFilter قبل و بعد از View تغییر خروجی

Authorization Filter – کنترل دسترسی قبل از اجرا

📘 تعریف:

اولین نقطه بررسی درخواست. این فیلتر مشخص می‌کنه آیا کاربر اصلاً اجازه‌ی اجرای اکشن رو داره یا نه.

🧪 مثال واقعی:

				
					public class RoleCheckFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var user = context.HttpContext.User;

        if (!user.Identity.IsAuthenticated || !user.IsInRole("Admin"))
        {
            context.Result = new ForbidResult();
        }
    }
}

				
			

Resource Filter – منطق قبل از مدل بایندینگ

📘 تعریف:

اگر بخوای زمان اجرای درخواست رو اندازه بگیری یا قبل از اینکه پارامترها Bind بشن کش یا توکن خاصی چک کنی، اینجا جای کاره.

🧪 مثال واقعی:

				
					public class TimerResourceFilter : IResourceFilter
{
    private Stopwatch _sw;

    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        _sw = Stopwatch.StartNew();
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        _sw.Stop();
        Console.WriteLine($"Request took {_sw.ElapsedMilliseconds}ms");
    }
}

				
			

Action Filter – لاگ‌گیری و اعتبارسنجی قبل/بعد اکشن

📘 تعریف:

اجرای کد درست قبل از متد Action و درست بعد از اون. این فیلتر برای لاگ، مانیتورینگ و حتی Validate کردن ورودی خیلی به درد می‌خوره.

🧪 مثال واقعی:

				
					public class AuditActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext 
    context, ActionExecutionDelegate next)
    {
        Console.WriteLine("Before Action");
        var result = await next();
        Console.WriteLine("After Action");
    }
}

				
			

Exception Filter – مدیریت خطاهای سراسری

📘 تعریف:

اگر بخوای توی کل اپلیکیشن خطاها رو یکجا مدیریت کنی و خروجی‌ کنترل‌شده بدی، این فیلتر کاملاً برات مناسبه.

🧪 مثال واقعی:

				
					public class GlobalExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        context.Result = new JsonResult(new
        {
            error = "Moshkeli Ejad Shode!",
            detail = context.Exception.Message
        });
        context.ExceptionHandled = true;
    }
}

				
			

Result Filter – تغییر در خروجی View یا JSON

📘 تعریف:

اگر بخوای چیزی به ViewData اضافه کنی یا یه Header خاص توی Response بذاری، قبل از اینکه جواب برای کلاینت ارسال بشه، این فیلتر وارد می‌شه.

🧪 مثال واقعی:

				
					public class InjectViewDataFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is ViewResult result)
        {
            result.ViewData["Message"] = "🔔 Injected from filter";
        }
    }

    public void OnResultExecuted(ResultExecutedContext context) { }
}

				
			

مقایسه فیلترها در ASP.NET Core

مقایسه Filters:

فیلتر مناسب برای زمان اجرا
Authorization بررسی نقش‌ها و مجوزها اولین در pipeline
Resource کش و تایمینگ قبل از مدل بایندینگ
Action اعتبارسنجی، لاگ قبل و بعد از اکشن
Exception هندل خطاهای سراسری در صورت Exception
Result تغییر در ViewData یا JSON قبل و بعد از خروجی

نحوه ثبت و استفاده از فیلترها

۱. سراسری (Global Filters) فایل program.cs:

				
					services.AddControllersWithViews(options =>
{
    options.Filters.Add<GlobalExceptionFilter>();
});

				
			

۲. روی کنترلر یا اکشن:

				
					[ServiceFilter(typeof(AuditActionFilter))]
public IActionResult Index() => View();

				
			

۳. با TypeFilter به صورت Attribute (در صورت نیاز به پارامتر ورودی):

				
					[TypeFilter(typeof(RoleCheckFilter), Arguments = new object[] 
{ "Admin" })]

				
			

چرا فیلترها در ASP.NET Core حیاتی هستند؟

  • ✅ رعایت کامل اصل تفکیک مسئولیت (SRP)
  • ✅ امکان پیاده‌سازی Cross-Cutting Concerns تمیز
  • ✅ سازگاری کامل با Dependency Injection
  • ✅ قابل تست و قابل توسعه
  • ✅ خوانایی بهتر و نگهداری آسان‌تر پروژه

سوالات متداول درباره Filters در ASP.NET Core

ServiceFilter: از DI (Dependency Injection) استفاده می‌کنه و باید فیلتر در Startup یا Program در IServiceCollection ثبت شده باشه.

TypeFilter: از DI هم پشتیبانی می‌کنه، اما نیازی به ثبت در DI نداره و به‌صورت درجا نمونه‌سازی میشه. مناسب برای فیلترهایی با پارامتر.

Attribute: فقط برای فیلترهایی استفاده میشه که پارامتر ندارن و نیازی به تزریق وابستگی ندارن. ساده و مستقیم.

می‌تونی با پیاده‌سازی IExceptionFilter یا IAsyncExceptionFilter یک کلاس هندل‌کننده‌ی خطا بسازی، و بعد اون رو به صورت global در Program.cs اضافه کنی:

services.AddControllersWithViews(options =>
  {
options.Filters.Add<GlobalExceptionFilter>();
  });

این کار باعث میشه همه‌ی خطاهای برنامه به‌صورت یکجا هندل بشن، مثلاً به شکل JSON خروجی داده بشه یا لاگ‌گیری انجام بشه.

  • اگر منطق فقط برای کنترلرها یا اکشن‌ها لازمه → ✅ از Action Filter استفاده کن.
  • اگر نیاز به پردازش کل request pipeline داری → بهتره از Middleware استفاده بشه.
  • اگر منطق خیلی سبک و بدون وابستگیه → یه Attribute ساده می‌تونه کافی باشه.

پس، اگر می‌خوای روی اکشن‌ها متمرکز باشی و از DI هم استفاده کنی، ActionFilter بهترین انتخابه.

بله، می‌تونی چند فیلتر مختلف روی یک کنترلر یا اکشن استفاده کنی. ASP.NET Core بر اساس نوع فیلتر و ترتیب تعریف‌شدن در pipeline، ترتیب اجرا رو تعیین می‌کنه:

ترتیب اجرا (Forward):
AuthorizationResourceActionResult

ترتیب بازگشت (Backward):
ResultActionResource

اگر چندتا از یک نوع فیلتر استفاده کنی، ترتیبشون بر اساس ترتیب افزودن در collection یا کد هست.

نتیجه‌گیری

فیلترها در ASP.NET Core مثل نگهبان‌های پشت صحنه‌ هستن.

بدون اینکه کدهای اصلی اکشن‌ها شلوغ بشه، می‌تونی کارهای زیادی مثل کنترل دسترسی، لاگ‌گیری، هندل خطا، تزریق اطلاعات به View و کلی چیز دیگه رو انجام بدی.

اگر هنوز ازشون استفاده نمی‌کنی، بهت پیشنهاد می‌کنم همین حالا شروع کنی چون واقعاً پروژه‌ت رو تمیزتر، امن‌تر و حرفه‌ای‌تر می‌کنه.

📢 نظر شما چیست؟ اگر شما هم اطلاعات و تجربه خوبی در استفاده از Action Filters در آموزش ASP.NET Core دارید خوشحال میشم در بخش نظرات، تجربه های ارزشمندتان را با ما به اشتراک بگذارید! 🚀

سؤالی درباره این مقاله داری؟

اگر نکته‌ای در این مقاله برات مبهم بود یا خواستی بیشتر بدونی، همین حالا برام بنویس تا دقیق و صمیمی پاسخت رو بدم — مثل یه گفت‌وگوی واقعی 💬

برو به صفحه پرسش و پاسخ

میثم راد

من یه برنامه نویسم که حسابی با دیتابیس اوراکل رفیقم! از اونایی ام که تا چیزی رو کامل نفهمم،ول کن نیستم، یادگرفتن برام مثل بازیه، و نوشتن اینجا کمک می کنه تا چیزایی که یاد گرفتم رو با بقیه به شریک بشم، با هم پیشرفت کنیم.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *