0Pricing
C# Academy · Lección

Descripción general de la canalización de ASP.NET Core

Comprenda cómo fluyen las solicitudes por la canalización de middleware y HttpContext, y cómo se construyen las respuestas.

Descripción general de la canalización de ASP.NET Core es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

El pipeline de solicitudes

Cada solicitud HTTP en ASP.NET Core fluye a través de un pipeline de middleware. Cada componente de middleware puede inspeccionar, modificar, interrumpir o reenviar la solicitud al componente siguiente. Comprender este pipeline es fundamental para crear aplicaciones de ASP.NET Core.

HttpContext: el contenedor de la solicitud

HttpContext contiene toda la información de una solicitud y su respuesta: encabezados, cookies, cuerpo, notificaciones del usuario, información de la conexión y el token de cancelación. Todo el middleware opera sobre él.

app.Use(async (context, next) =>
{
    // Read request info
    var method  = context.Request.Method;
    var path    = context.Request.Path;
    var headers = context.Request.Headers;
    var user    = context.User.Identity?.Name;

    // Write to response
    context.Response.Headers.Append("X-Processed-By", "MyMiddleware");

    await next(context); // forward to next middleware
});

Orden de registro del middleware

El middleware se ejecuta en el orden en que se registra. La respuesta se deshace en orden inverso, como una pila. El orden es fundamental: la autenticación debe ejecutarse antes que la autorización, y el enrutamiento antes de la coincidencia con los endpoints.

// Typical order for an ASP.NET Core app:
app.UseExceptionHandler("/error"); // outermost — catches everything
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("policy");
app.UseAuthentication();  // must be before Authorization
app.UseAuthorization();
app.UseRateLimiter();
app.UseOutputCache();
// MapHub, MapControllers, MapGet etc.
app.Run();

Use, Run y Map

Tres métodos agregan middleware: Use (llama al siguiente), Run (terminal, nunca llama al siguiente) y Map (crea una bifurcación según la ruta).

// Use: passes to next
app.Use(async (ctx, next) =>
{
    Console.WriteLine("Before");
    await next(ctx);
    Console.WriteLine("After");
});

// Run: terminal — no next
app.Run(async ctx =>
    await ctx.Response.WriteAsync("Terminal"));

// Map: branch on path prefix
app.Map("/api", apiApp =>
    apiApp.Run(async ctx =>
        await ctx.Response.WriteAsync("API branch")));

Cuerpos de las solicitudes y respuestas

Los cuerpos de las solicitudes y las respuestas son streams. La lectura del cuerpo de una solicitud solo puede hacerse una vez; habilite el almacenamiento en búfer del cuerpo si necesita leerlo varias veces, por ejemplo, en varios componentes de middleware.

app.Use(async (ctx, next) =>
{
    // Enable buffering so body can be read multiple times
    ctx.Request.EnableBuffering();

    using var reader = new StreamReader(
        ctx.Request.Body,
        leaveOpen: true);
    var body = await reader.ReadToEndAsync();
    ctx.Request.Body.Position = 0; // rewind for next middleware

    Console.WriteLine($"Body: {body}");
    await next(ctx);
});

Interrupción del pipeline

El middleware puede interrumpir el pipeline escribiendo la respuesta y NO llamando a next. Esto resulta útil para controles de autenticación, comprobaciones de estado o páginas de mantenimiento.

app.Use(async (ctx, next) =>
{
    if (ctx.Request.Path == "/maintenance")
    {
        ctx.Response.StatusCode = 503;
        await ctx.Response.WriteAsync("Service under maintenance");
        return; // short-circuit — next is NOT called
    }
    await next(ctx);
});

La interfaz IMiddleware

Para crear middleware basado en clases que necesite DI, implemente IMiddleware. Registre la implementación en DI y use app.UseMiddleware<T>().

public class RequestTimingMiddleware : IMiddleware
{
    private readonly ILogger<RequestTimingMiddleware> _logger;
    public RequestTimingMiddleware(ILogger<RequestTimingMiddleware> l) => _logger = l;

    public async Task InvokeAsync(HttpContext ctx, RequestDelegate next)
    {
        var sw = System.Diagnostics.Stopwatch.StartNew();
        await next(ctx);
        _logger.LogInformation("{Method} {Path}: {Ms}ms",
            ctx.Request.Method, ctx.Request.Path, sw.ElapsedMilliseconds);
    }
}

// Register:
builder.Services.AddTransient<RequestTimingMiddleware>();
app.UseMiddleware<RequestTimingMiddleware>();

Clases de middleware convencionales

Como alternativa, cree una clase con un método InvokeAsync(HttpContext, RequestDelegate). El framework inyecta las dependencias, incluido el delegado siguiente, mediante el constructor.

public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private readonly string _key;

    // RequestDelegate injected by framework
    public ApiKeyMiddleware(RequestDelegate next, IConfiguration cfg)
    {
        _next = next;
        _key = cfg["ApiKey"] ?? "";
    }

    public async Task InvokeAsync(HttpContext ctx)
    {
        if (ctx.Request.Headers["X-Api-Key"] != _key)
        {
            ctx.Response.StatusCode = 401;
            return;
        }
        await _next(ctx);
    }
}

Modificación de respuestas después de next

El código que aparece después de await next(ctx) se ejecuta cuando la respuesta ya ha empezado a escribirse. Puede agregar encabezados de respuesta antes de next, pero no puede modificar el código de estado ni el cuerpo después de ese punto.

app.Use(async (ctx, next) =>
{
    // Before: add response headers (safe)
    ctx.Response.OnStarting(() =>
    {
        ctx.Response.Headers.Append("X-Request-Id",
            Guid.NewGuid().ToString("N"));
        return Task.CompletedTask;
    });

    await next(ctx);

    // After: response may already be sent
    // SAFE: logging, metrics
    // UNSAFE: changing status code or writing body
    Console.WriteLine($"Response status: {ctx.Response.StatusCode}");
});

Caso real: middleware de ID de correlación

Un middleware de ID de correlación de producción que agrega un ID de traza a cada solicitud para el seguimiento distribuido y el registro.

public class CorrelationIdMiddleware
{
    private readonly RequestDelegate _next;
    private const string Header = "X-Correlation-Id";

    public CorrelationIdMiddleware(RequestDelegate next) => _next = next;

    public async Task InvokeAsync(HttpContext ctx)
    {
        var correlationId = ctx.Request.Headers[Header].FirstOrDefault()
            ?? Guid.NewGuid().ToString("N");

        ctx.Items["CorrelationId"] = correlationId;

        ctx.Response.OnStarting(() =>
        {
            ctx.Response.Headers.Append(Header, correlationId);
            return Task.CompletedTask;
        });

        using (Serilog.Context.LogContext.PushProperty("CorrelationId", correlationId))
            await _next(ctx);
    }
}

Comprobación rápida

¿Cuál es la diferencia entre app.Use() y app.Run() al agregar middleware?

Resumen: introducción al pipeline de ASP.NET Core

Conclusiones clave:

  • El middleware se ejecuta en el orden de registro; las respuestas se deshacen en orden inverso
  • Use → llama al siguiente; Run → terminal; Map → bifurcación basada en la ruta
  • HttpContext contiene la solicitud, la respuesta, el usuario y el token de cancelación
  • Habilite el almacenamiento en búfer para leer el cuerpo de la solicitud varias veces
  • La interfaz IMiddleware permite crear middleware basado en clases compatible con DI
  • Agregue encabezados de respuesta mediante OnStarting(); no cambie el estado después de next

Preguntas frecuentes

¿La lección «Descripción general de la canalización de ASP.NET Core» es gratis?

Sí — el texto completo de «Descripción general de la canalización de ASP.NET Core» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Descripción general de la canalización de ASP.NET Core»?

Comprenda cómo fluyen las solicitudes por la canalización de middleware y HttpContext, y cómo se construyen las respuestas. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Descripción general de la canalización de ASP.NET Core»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Descripción general de la canalización de ASP.NET Core
  2. Escritura de middleware personalizado
  3. Cortocircuito y ramificación
  4. Orden del middleware y middleware integrado
← Volver a C# Academy