Cómo crear middlewares en ASP.NET Core

Resumen

Los middlewares en ASP.NET Core son piezas de lógica que procesan cada request en tu API desde que entra hasta que sale. Entender cómo funcionan te permite estructurar mejor tus proyectos en .NET y responder con seguridad cualquier pregunta técnica en una entrevista.

Cada middleware ejecuta una pequeña tarea, como una validación, una transformación de datos o una búsqueda en el servidor, y luego pasa el control al siguiente. Cuando el último termina, la respuesta regresa atravesando otra vez la cadena hasta llegar al cliente.

Cómo funciona el pipeline de middlewares en .NET

La documentación oficial de Microsoft llama pipeline o tubería a esta secuencia ordenada. El orden importa porque cada middleware depende del anterior para hacer su trabajo correctamente.

En un proyecto típico de ASP.NET Core encuentras este orden recomendado:

  • CORS, que valida qué clientes pueden consumir tu API.
  • Autenticación, que identifica al usuario que hace el request.
  • Autorización, que verifica si ese usuario tiene permisos.
  • Custom middlewares, los que tú creas para necesidades específicas.
  • Endpoints (MapControllers), que ejecuta la lógica final del controlador.

¿Qué es un middleware en ASP.NET Core? Es un componente que intercepta cada request HTTP, ejecuta una porción de lógica y decide si pasa el control al siguiente middleware en el pipeline.

La respuesta no siempre tiene que ser positiva. Puede ser un error, pero igual debe recorrer los middlewares para que cada uno haga la validación correspondiente al escenario [01:15].

Dónde se configuran los middlewares en Program.cs

Toda la configuración del pipeline vive en la parte inferior del archivo Program.cs. Ahí encuentras llamadas como UseCors, UseHttpsRedirection, UseAuthorization y MapControllers, ya ordenadas por defecto cuando creas el proyecto.

Los custom middlewares deben ir entre la autorización y el MapControllers. No es obligatorio, pero es la recomendación para no romper la secuencia que ASP.NET Core espera [03:45].

Cómo crear un middleware rápido con app.Use

Para una primera prueba puedes usar el método genérico Use directamente en Program.cs. Recibe dos parámetros clave que verás en todos los middlewares:

  • context: contiene el request completo, con path, encabezados, cookies y parámetros que envía el cliente.
  • next: una función que avisa al siguiente middleware que ya puede ejecutarse.

Un ejemplo mínimo imprime en consola el path del request, llama a await next.Invoke() y después imprime el context.Response.StatusCode con la respuesta procesada.

csharp app.Use(async (context, next) => { Console.WriteLine($"Request: {context.Request.Path}"); await next.Invoke(); Console.WriteLine($"Response: {context.Response.StatusCode}"); });

Al ejecutar el proyecto y llamar api/WeatherForecast, la consola muestra el path y un 200. Si pasas un parámetro inválido como api/WeatherForecast/50, verás un 400 Bad Request, confirmando que el middleware intercepta tanto request como respuesta [05:30].

Cómo crear un middleware en un archivo separado

Escribir middlewares directamente en Program.cs sirve para demos, pero en proyectos reales conviene aislarlos. La práctica recomendada es crear una carpeta Middlewares y dentro una clase, por ejemplo RequestLoginMiddleware.cs.

La estructura básica que necesitas es:

  • Recibir un RequestDelegate en el constructor, que cumple el rol de next.
  • Implementar el método InvokeAsync(HttpContext context), presente en todos los middlewares.
  • Ejecutar tu lógica antes y después de llamar a await _next(context).

csharp public class RequestLoginMiddleware { private readonly RequestDelegate _next;

public RequestLoginMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { Console.WriteLine($"Middleware Request: {context.Request.Path}"); await _next(context); Console.WriteLine($"Middleware Response: {context.Response.StatusCode}"); }

}

Por qué usar un método de extensión para tu middleware

Es opcional, pero muy útil crear una clase RequestLoginMiddlewareExtensions con un método UseRequestLogin. Eso te permite registrarlo en Program.cs con la misma estética que UseCors o UseAuthorization, dejando el archivo mucho más limpio.

csharp public static class RequestLoginMiddlewareExtensions { public static IApplicationBuilder UseRequestLogin(this IApplicationBuilder app) { return app.UseMiddleware<RequestLoginMiddleware>(); } }

Después, en Program.cs, basta con llamar app.UseRequestLogin(); en la posición correcta del pipeline [08:20].

¿Para qué sirve el método InvokeAsync en un middleware? Es el punto de entrada que ASP.NET Core llama por cada request. Recibe el HttpContext, ejecuta tu lógica y delega el control al siguiente middleware con await _next(context).

Retos para practicar middlewares en ASP.NET Core

Para afianzar el concepto, prueba estos dos ejercicios sobre tu proyecto:

  1. Mueve UseCors después de MapControllers y consume la API desde un cliente HTML o React. Observa si sigue funcionando y entiende por qué el orden importa.
  2. Modifica RequestLoginMiddleware para que use un timer y mida cuánto tarda cada request del inicio al fin, en lugar de imprimir solo el path y el status code.

Los middlewares te ayudan a centralizar logging, agregar datos a los encabezados, manejar autenticación y capturar excepciones de forma global. ¿Qué middleware personalizado te gustaría construir primero en tu API? Cuéntalo en los comentarios.