Ответ
Да, создание кастомного middleware — стандартная практика для сквозной функциональности (cross-cutting concerns). Например, для логирования, обработки исключений, кастомной аутентификации или добавления специфичных заголовков.
Пример: Middleware для логирования времени выполнения запроса и добавления корреляционного ID.
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestLoggingMiddleware> _logger;
public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
// Генерация уникального ID для отслеживания цепочки запроса.
var correlationId = Guid.NewGuid().ToString();
context.Items["CorrelationId"] = correlationId;
var stopwatch = Stopwatch.StartNew();
// Логируем начало обработки.
_logger.LogInformation(
"Starting request {Method} {Path} with CorrelationId: {CorrelationId}",
context.Request.Method,
context.Request.Path,
correlationId
);
try
{
// Передаём управление следующему компоненту в конвейере.
await _next(context);
}
finally
{
stopwatch.Stop();
// Логируем завершение обработки и время выполнения.
_logger.LogInformation(
"Completed request {Method} {Path} with status {StatusCode} in {ElapsedMs}ms. CorrelationId: {CorrelationId}",
context.Request.Method,
context.Request.Path,
context.Response.StatusCode,
stopwatch.ElapsedMilliseconds,
correlationId
);
}
}
}
// Метод расширения для удобной регистрации.
public static class RequestLoggingMiddlewareExtensions
{
public static IApplicationBuilder UseRequestLogging(this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestLoggingMiddleware>();
}
}
Регистрация в конвейере (Program.cs):
var app = builder.Build();
// Порядок важен! Логирование должно быть одним из первых.
app.UseRequestLogging();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Зачем это нужно? Такой middleware централизует логирование для всех запросов, добавляет полезный контекст (CorrelationId) и помогает в диагностике проблем с производительностью, не загрязняя код контроллеров.