Как использовать фильтры обработчиков маршрутов в минимальных API в ASP.NET Core 7

автор vadim


В ASP.NET Core 6 представлена ​​упрощенная модель хостинга, которая позволяет нам создавать облегченные API с минимальными зависимостями. Минимальные API в ASP.NET Core 6 не используют контроллеры и не поддерживают ряд полезных функций ASP.NET. Одной из таких недостающих функций являются фильтры.

Однако с помощью ASP.NET Core 7 (теперь доступного в качестве кандидата на выпуск) мы можем воспользоваться преимуществами недавно представленного интерфейса IRouteHandlerFilter для включения фильтров в наши минимальные API. Эти фильтры можно использовать для изменения объектов запроса или ответа по желанию или для сокращения конвейера обработки запросов.

В этой статье обсуждается, как мы можем работать с фильтрами обработчиков маршрутов при создании минимальных приложений API в ASP.NET Core 7. Чтобы использовать примеры кода, представленные в этой статье, в вашей системе должна быть установлена ​​предварительная версия Visual Studio 2022. Если у вас еще нет копии, вы можете скачать Visual Studio 2022 здесь.

Создайте минимальный проект веб-API ASP.NET Core 7 в Visual Studio 2022.

Прежде всего давайте создадим проект ASP.NET Core 7 в Visual Studio 2022 Preview. Следуй этим шагам:

  1. Запустите среду разработки Visual Studio 2022 Preview.
  2. Нажмите «Создать новый проект».
  3. В окне «Создать новый проект» выберите «ASP.NET Core Web API» из списка отображаемых шаблонов.
  4. Нажмите “Далее.
  5. В окне «Настроить новый проект» укажите имя и местоположение нового проекта.
  6. При желании установите флажок «Поместить решение и проект в один каталог», в зависимости от ваших предпочтений.
  7. Нажмите “Далее.
  8. В следующем окне «Дополнительная информация» снимите флажок «Использовать контроллеры…», поскольку в этом примере мы будем использовать минимальные API. В поле «Тип аутентификации» оставьте значение «Нет» (по умолчанию).
  9. Убедитесь, что флажки «Включить Docker», «Настроить HTTPS» и «Включить поддержку Open API» сняты, поскольку мы не будем здесь использовать ни одну из этих функций.
  10. Нажмите Создать.

Мы будем использовать этот проект веб-API ASP.NET Core 7 для создания минимального API и реализации фильтров обработчиков маршрутов в разделах ниже.

Что такое фильтры? Почему мы должны их использовать?

Фильтры позволяют запускать код на определенных этапах конвейера обработки запросов. Другими словами, фильтр — это фрагмент кода, который выполняется до или после выполнения метода действия. Например, вы можете использовать фильтр для регистрации каждый раз, когда кто-то обращается к веб-странице, или для проверки параметров запроса, отправленных в конечную точку.

Фильтры имеют ряд преимуществ:

  • Фильтры повышают безопасность вашего приложения, позволяя отклонять запросы, не соответствующие определенным критериям (включая авторизацию).
  • Фильтры могут помочь вам очистить ваш код, создавая повторно используемые функции и классы.
  • Фильтры позволяют вам сосредоточиться на бизнес-логике вашего приложения вместо того, чтобы тратить время на написание кода для решения сквозных задач, таких как ведение журнала, обработка исключений и безопасность.

Почему нам следует использовать фильтры в минимальных API?

Вы можете воспользоваться фильтрами в минимальных API для написания кода, который может выполнять следующие действия:

  • Выполняйте код до и после обработчика конечной точки.
  • Проверяйте и редактируйте параметры при выполнении обработчика конечной точки.
  • Проверьте поведение ответа обработчика конечной точки.
  • Записывать метаданные запросов и ответов.
  • Убедитесь, что запрос нацелен на поддерживаемую версию API.
  • Проверьте запрос и параметры запроса.

Интерфейс IRouteHandlerFilter в ASP.NET Core 7.

Вы можете воспользоваться интерфейсом IRouteHandlerFilter, чтобы изменить запрос или ответ или сократить конвейер обработки запросов. Вы также можете добавить сквозные задачи, такие как аутентификация, авторизация и ведение журнала. Вкратце, вот чего вы можете достичь с помощью этого интерфейса:

  • Напишите собственную логику для обработки входящих запросов.
  • Перехватите запрос и измените объект запроса по мере необходимости.
  • Внесите изменения в ответ перед его отправкой.
  • Замкните запрос, что означает, что все оставшиеся фильтры действий не будут выполнены.

Следующий фрагмент кода иллюстрирует интерфейс IRoutehandler:

namespace Microsoft.AspNetCore.Http;
public interface IRouteHandlerFilter
{
    ValueTask<object?> InvokeAsync(
        RouteHandlerInvocationContext context,
        RouteHandlerFilterDelegate next);
}

Создайте собственный фильтр обработчика маршрутов в ASP.NET Core 7.

Вы можете создать собственный класс фильтра через интерфейс IRouteHandlerFilter, как показано в листинге кода, приведенном ниже.

public class DemoFilter : IRouteHandlerFilter
{
    private ILogger _logger;
    public DemoFilter(ILoggerFactory loggerFactory)
    {
       _logger = logger;
    }
    public async ValueTask<object?> InvokeAsync(RouteHandlerInvocationContext context, RouteHandlerFilterDelegate next)
   {
        var text = context.GetParameters[0];
       if (text.Equals("Error"))
       {
          _logger.LogInformation(“Error.”);
          return Results.Problem("This is a minimal example of an error.");
       }
       _logger.LogInformation(“Success.”);
       return await next(context);
   }
}

Затем вам следует зарегистрировать фильтр как службу в файле Program.cs, используя следующий фрагмент кода.

builder.Services.AddSingleton<DemoFilter>();

Фильтр можно зарегистрировать с помощью RouteHandlerFilterDelegate или метода расширения AddFilter. В этом примере мы будем использовать метод расширения AddFilter. Напишите следующий фрагмент кода в файле Program.cs.

app.MapGet("/v1/MyDemoEndpoint{text}", “Hello”)
   .AddFilter<DemoFilter>();

Создайте фильтр короткого замыкания в ASP.NET Core 7.

Часто вам может потребоваться короткое замыкание конвейера обработки запросов. Например, предположим, что вы создали приложение на основе микросервисов, и один из сервисов не отвечает. В этом случае все запросы к этому сервису завершатся неудачно. Вместо этого вы можете замкнуть конвейер обработки запросов и обратиться к какой-нибудь другой исправной службе.

Короткое замыкание часто является желаемым действием, чтобы избежать ненужной обработки. Например, если запрос генерируется для статических файлов, таких как HTML, CSS и JavaScript, вы можете написать фильтр, который будет перехватывать, обрабатывать и обслуживать этот запрос, одновременно сокращая остальную часть конвейера. Короткое замыкание останавливает конвейер обработки запросов и перенаправляет запрос на резервный метод или службу.

Другим примером короткого замыкания является шаблон автоматического выключателя в приложениях на основе микросервисов. Этот шаблон не позволяет приложению выполнять операцию, которая может привести к сбою. Обычно автоматические выключатели перенаправляют запросы на резервный метод, если у вас возникают проблемы со службой или методом службы. Таким образом, когда из-за сбоя службы возникает сбой, вы можете использовать автоматические выключатели для перенаправления запроса к резервным службам или методам.

Вот как вы можете реализовать собственный фильтр короткого замыкания для вашего минимального API:

public class MyShortCircuitFilter: IRouteHandlerFilter
{
    public ValueTask<object?> InvokeAsync(
        RouteHandlerInvocationContext context,
        RouteHandlerFilterDelegate next)
    {
        return new ValueTask<object?>(Results.Json
        (new { Message = "Terminated" }));
    }
}

Фильтры позволяют запускать собственный код до или после определенного момента в конвейере обработки запросов. Они также помогают избежать дублирования кода в действиях. Интерфейс IRouteHandlerFilter — это специальный фильтр, который можно применить ко всему маршруту или к одному обработчику. Это позволяет вам получить доступ к объекту запроса, а затем изменить запрос или ответ по мере необходимости.

Related Posts

Оставить комментарий