Panoramica della pipeline di ASP.NET Core
Comprenda come le richieste attraversano la pipeline dei middleware e HttpContext e come vengono costruite le risposte.
Panoramica della pipeline di ASP.NET Core è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
La pipeline delle richieste
Ogni richiesta HTTP in ASP.NET Core attraversa una pipeline di middleware. Ogni componente middleware può esaminare, modificare, interrompere o inoltrare la richiesta al componente successivo. Comprendere questa pipeline è fondamentale per creare app ASP.NET Core.
HttpContext: l'involucro della richiesta
HttpContext contiene tutte le informazioni relative a richiesta e risposta: intestazioni, cookie, corpo, attestazioni dell'utente, informazioni sulla connessione e token di annullamento. Tutti i middleware operano su di esso.
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
});Ordine di registrazione dei middleware
I middleware vengono eseguiti nell'ordine in cui sono registrati. La risposta viene riavvolta nell'ordine inverso, come in uno stack. L'ordine è fondamentale: l'autenticazione deve essere eseguita prima dell'autorizzazione; il routing prima della corrispondenza con gli endpoint.
// 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 e Map
Tre metodi aggiungono middleware: Use, che chiama il successivo; Run, terminale, che non chiama mai il successivo; e Map, che crea diramazioni in base al percorso.
// 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")));Corpi delle richieste e delle risposte
I corpi delle richieste e delle risposte sono flussi. Il corpo della richiesta può essere letto una sola volta: abiliti il buffering del corpo della richiesta se deve essere letto più volte, ad esempio in più 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);
});Interruzione anticipata della pipeline
Un middleware può interrompere anticipatamente la pipeline scrivendo la risposta e NON chiamando next. È utile per i controlli di autenticazione, i controlli di integrità o le pagine di manutenzione.
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);
});L'interfaccia IMiddleware
Per un middleware basato su classi che necessita dell'inserimento delle dipendenze, implementi IMiddleware. Registri l'implementazione nel contenitore DI e utilizzi 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>();Classi di middleware convenzionali
In alternativa, crei una classe con un metodo InvokeAsync(HttpContext, RequestDelegate). Il framework inserisce le dipendenze, incluso il delegato successivo, tramite il costruttore.
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);
}
}Modificare le risposte dopo next
Il codice dopo await next(ctx) viene eseguito dopo l'inizio della scrittura della risposta. È possibile aggiungere intestazioni alla risposta prima di next, ma non è possibile modificare il codice di stato o il corpo dopo questo 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 reale: middleware per l'ID di correlazione
Un middleware per l'ID di correlazione, usato in produzione, aggiunge un ID di traccia a ogni richiesta per la traccia distribuita e la registrazione dei log.
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);
}
}Verifica rapida
Qual è la differenza tra app.Use() e app.Run() quando si aggiunge un middleware?
Riepilogo: panoramica della pipeline ASP.NET Core
Punti chiave:
- I middleware vengono eseguiti nell'ordine di registrazione; le risposte vengono riavvolte nell'ordine inverso
- Use → chiama il successivo; Run → terminale; Map → diramazione basata sul percorso
- HttpContext contiene richiesta, risposta, utente e token di annullamento
- Abiliti il buffering per leggere più volte il corpo della richiesta
- L'interfaccia IMiddleware consente middleware basati su classi compatibili con DI
- Aggiunga le intestazioni della risposta tramite OnStarting(); non modifichi lo stato dopo next
Domande Frequenti
La lezione «Panoramica della pipeline di ASP.NET Core» è gratuita?
Sì — il testo completo di «Panoramica della pipeline di ASP.NET Core» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Panoramica della pipeline di ASP.NET Core»?
Comprenda come le richieste attraversano la pipeline dei middleware e HttpContext e come vengono costruite le risposte. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Panoramica della pipeline di ASP.NET Core»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Panoramica della pipeline di ASP.NET Core
- Scrittura di middleware personalizzati
- Interruzione anticipata e ramificazione
- Ordine dei middleware e middleware integrati