Sobes.tech
Middle+

Как прилагате филтри в конвейерите (pipeline) в C#? Можете ли да дадете примери за тяхното използване?

sobes.tech AI

Отговор от AI

Филтрите в C# pipelines се използват за прихващане и намеса в различни етапи на обработка на заявката или изпълнение на задача. В уеб приложенията ASP.NET Core те позволяват добавяне на логика преди, след или по време на изпълнение на методите на контролерите, както и на други нива на обработка на заявки.

Примери за използване на филтри в ASP.NET Core:

  1. Аутентикация и Авторизация (Authentication/Authorization Filters): Определят дали потребителят има право да изпълни дадено действие.

    // Пример за атрибут Authorize
    [Authorize]
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
    
  2. Филтри за ресурси (Resource Filters): Изпълняват се първи след филтрите за авторизация. Могат да кешират или да прекъснат потока.

    // Пример за филтър за ресурси за кеширане
    public class CacheResourceFilter : IResourceFilter
    {
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            // Логика преди изпълнение на метода на действието
        }
    
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            // Логика след изпълнение на метода на действието, преди записване на отговора
        }
    }
    
  3. Филтри за действия (Action Filters): Изпълняват се преди и след изпълнение на метода на действието. Подходящи за валидиране на данни, логиране или модифициране на параметри и резултати.

    // Пример за филтър за логиране
    public class LogActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            // Логика преди изпълнение на действието
            Console.WriteLine($"Изпълнява се действие: {context.ActionDescriptor.DisplayName}");
        }
    
        public void OnActionExecuted(ActionExecutedContext context)
        {
            // Логика след изпълнение на действието
            Console.WriteLine($"Изпълнено действие: {context.ActionDescriptor.DisplayName}");
        }
    }
    
    // Приложение на филтър за действие към метод на контролер
    [LogActionFilter]
    public IActionResult About()
    {
        return View();
    }
    
  4. Филтри за изключения (Exception Filters): Обработват необработени изключения, възникващи по време на изпълнение на метода на действието или други филтри.

    // Пример за филтър за изключения за обработка на грешки
    public class CustomExceptionFilter : IExceptionFilter
    {
        public void OnException(ExceptionContext context)
        {
            // Логика за обработка на изключението
            context.Result = new ContentResult()
            {
                Content = "Възникна грешка.",
                StatusCode = 500
            };
            context.ExceptionHandled = true; // Посочва, че изключението е обработено
        }
    }
    
    // Приложение на филтър за изключения към контролер
    [CustomExceptionFilter]
    public class ErrorController : Controller
    {
        public IActionResult Index()
        {
            throw new Exception("Нещо се обърка!");
        }
    }
    
  5. Филтри за резултати (Result Filters): Изпълняват се преди и след изпълнение на метода за резултат (например, преди или след изпълнение на ViewResult, JsonResult и др.).

    // Пример за филтър за резултат за модифициране на резултата
    public class CustomResultFilter : IResultFilter
    {
        public void OnResultExecuting(ResultExecutingContext context)
        {
            // Логика преди изпълнение на метода за резултат
            Console.WriteLine($"Тип на резултата: {context.Result.GetType().Name}");
        }
    
        public void OnResultExecuted(ResultExecutedContext context)
        {
            // Логика след изпълнение на метода за резултат
            Console.WriteLine($"Тип на изпълнения резултат: {context.Result.GetType().Name}");
        }
    }
    

Филтрите могат да бъдат приложени глобално (за всички заявки), на ниво контролер или на ниво конкретен метод. Техният ред на изпълнение в pipeline се определя от техния тип.