Ответ
Middleware — это компоненты, которые образуют конвейер обработки HTTP-запроса и ответа в приложении ASP.NET Core. Каждый middleware выполняет определенную задачу (логирование, аутентификация, обработка ошибок) и либо передает запрос дальше по цепочке, либо завершает обработку.
Ключевые принципы:
- Конвейер: Middleware регистрируются в
Program.cs(илиStartup.Configure) в определенном порядке. Этот порядок критически важен. - Вызов
next: Middleware решает, передать ли управление следующему компоненту в конвейере, вызвавnext.Invoke(). - Короткое замыкание: Middleware может не вызывать
next, тем самым завершая конвейер и отправляя ответ клиенту (например, middleware для статических файлов или аутентификации при неудаче).
Типичная структура конвейера:
// Program.cs
var app = builder.Build();
// 1. Обработка исключений (должен быть первым, чтобы ловить ошибки со всех последующих этапов)
app.UseExceptionHandler("/Error");
// 2. Обслуживание статических файлов (CSS, JS, изображения)
app.UseStaticFiles();
// 3. Маршрутизация (определяет, какой контроллер/метод запустить)
app.UseRouting();
// 4. Аутентификация и авторизация
app.UseAuthentication();
app.UseAuthorization();
// 5. Конечные точки (запуск контроллеров, Minimal API)
app.MapControllers();
app.Run();
Создание собственного Middleware: Есть два основных способа:
- Класс Middleware:
public class RequestTimingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<RequestTimingMiddleware> _logger; public RequestTimingMiddleware(RequestDelegate next, ILogger<RequestTimingMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { var sw = Stopwatch.StartNew(); await _next(context); // Передача управления дальше sw.Stop(); _logger.LogInformation($"Запрос {context.Request.Path} выполнен за {sw.ElapsedMilliseconds} мс"); } } // Регистрация: app.UseMiddleware<RequestTimingMiddleware>(); - Inline Middleware (удобно для простой логики):
app.Use(async (context, next) => { // Код до вызова next (обработка запроса) context.Response.Headers.Add("X-Request-Time", DateTime.UtcNow.ToString("o")); await next(); // Код после вызова next (обработка ответа) });
Встроенные Middleware: UseHttpsRedirection, UseCors, UseResponseCompression, UseSession и многие другие.