En ASP.NET Core, el middleware es uno de los componentes más importantes del pipeline de procesamiento de solicitudes. Cada petición HTTP pasa por una serie de middlewares antes de llegar al controlador o endpoint, y cada uno puede inspeccionar, modificar o incluso detener la solicitud y la respuesta. Crear un middleware personalizado te permite implementar funcionalidades reutilizables como registro de solicitudes, validaciones, auditorías, control de acceso, medición de tiempos de respuesta o manejo de encabezados personalizados.
La forma más sencilla de crear un middleware es mediante una clase que reciba un RequestDelegate en su constructor y exponga un método InvokeAsync.
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
public RequestLoggingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
Console.WriteLine($"Solicitud: {context.Request.Method} {context.Request.Path}");
await _next(context);
Console.WriteLine($"Respuesta: {context.Response.StatusCode}");
}
}
En este ejemplo, el middleware registra información antes y después de ejecutar el siguiente componente del pipeline. La llamada a _next(context) es fundamental, ya que permite que la solicitud continúe su recorrido. Si no se invoca, la ejecución termina en ese middleware.
Una vez creado, debes registrarlo en el pipeline de la aplicación.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseMiddleware<RequestLoggingMiddleware>();
app.MapControllers();
app.Run();
Para facilitar su uso, es recomendable crear un método de extensión.
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseRequestLogging(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestLoggingMiddleware>();
}
}
Ahora el registro queda mucho más limpio.
app.UseRequestLogging();
Los middlewares también pueden recibir servicios registrados en el contenedor de Dependency Injection directamente en el método InvokeAsync.
public async Task InvokeAsync(
HttpContext context,
ILogger<RequestLoggingMiddleware> logger)
{
logger.LogInformation("Procesando solicitud");
await _next(context);
}
Esto permite acceder a servicios como ILogger, configuraciones, repositorios o cualquier dependencia registrada sin necesidad de crearlas manualmente.
Es importante respetar el orden de los middlewares, ya que ASP.NET Core los ejecuta en el mismo orden en que se agregan. Por ejemplo, UseAuthentication() debe ejecutarse antes de UseAuthorization(), y un middleware de manejo de errores normalmente debe ubicarse al inicio del pipeline para capturar cualquier excepción producida por los componentes posteriores.
Crear middlewares personalizados es una excelente práctica para encapsular lógica transversal y mantener controladores y endpoints más limpios. Cuando se diseñan correctamente, mejoran la reutilización del código, facilitan el mantenimiento y permiten construir aplicaciones ASP.NET Core más organizadas, escalables y fáciles de probar.

