Какой жизненный цикл у middleware в ASP.NET Core?

«Какой жизненный цикл у middleware в ASP.NET Core?» — вопрос из категории ASP.NET Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Middleware в ASP.NET Core образует конвейер обработки HTTP-запроса и ответа. Каждый компонент middleware имеет четкий жизненный цикл в рамках одного запроса.

Основные этапы работы middleware:

  1. Входящая обработка (Before next): Middleware выполняет свою логику до передачи управления следующему компоненту в конвейере.
  2. Передача управления: Вызов next.Invoke() передает запрос следующему middleware. Если next не вызвать, цепочка обрывается (short-circuiting), что используется, например, в middleware для статических файлов или аутентификации.
  3. Исходящая обработка (After next): После того как следующий middleware и все последующие завершили работу, управление возвращается, и можно выполнить логику после обработки запроса (например, логирование, обработка исключений).

Порядок имеет значение: Middleware выполняются в том порядке, в котором они зарегистрированы в Program.cs (или Startup.Configure).

// Пример middleware, демонстрирующего жизненный цикл
app.Use(async (HttpContext context, RequestDelegate next) =>
{
    // 1. Действие ДО следующего middleware
    Console.WriteLine($"Before next: {context.Request.Path}");

    await next(context); // 2. Вызов следующего middleware в цепочке

    // 3. Действие ПОСЛЕ следующего middleware
    Console.WriteLine($"After next: {context.Response.StatusCode}");
});

// Следующий middleware в конвейере
app.UseRouting();
app.UseEndpoints(...);

Таким образом, жизненный цикл — это однонаправленный поток с возможностью "обернуть" обработку последующих компонентов.