0Pricing
C# Academy · Lezione

Interruzione anticipata e ramificazione

Usi MapWhen, UseWhen e middleware terminali per diramare o terminare la pipeline in base alle condizioni della richiesta.

Interruzione anticipata e ramificazione è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 3 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.

Diramazione e interruzione anticipata

Non tutte le richieste devono attraversare l'intera pipeline di middleware. ASP.NET Core offre strumenti per creare diramazioni, indirizzando sottoinsiemi di richieste verso pipeline diverse, e per interrompere anticipatamente l'elaborazione, restituendo subito una risposta.

Map: diramazione permanente per percorso

Map crea una diramazione permanente: le richieste che corrispondono al prefisso entrano nella diramazione e NON tornano mai alla pipeline principale.

app.Map("/api", apiApp =>
{
    apiApp.UseAuthentication();
    apiApp.UseAuthorization();
    apiApp.Run(async ctx =>
        await ctx.Response.WriteAsync("API branch"));
});

// Requests to /api/... enter the branch above.
// Requests to /public/... skip the branch entirely.
app.Run(async ctx =>
    await ctx.Response.WriteAsync("Main pipeline"));

MapWhen: diramazione basata su un predicato

MapWhen crea una diramazione in base a una condizione qualsiasi, come intestazioni, parametri di query o logica personalizzata. Come Map, la diramazione è permanente e non si ricongiunge alla pipeline principale.

// Branch when a specific header is present
app.MapWhen(
    ctx => ctx.Request.Headers.ContainsKey("X-Internal"),
    internalApp =>
    {
        internalApp.UseMiddleware<InternalApiMiddleware>();
        internalApp.Run(async ctx =>
            await ctx.Response.WriteAsync("Internal route"));
    });

// Branch on query parameter
app.MapWhen(
    ctx => ctx.Request.Query.ContainsKey("legacy"),
    legacyApp => legacyApp.UseMiddleware<LegacyHandlerMiddleware>());

UseWhen: diramazione condizionale con ricongiungimento

UseWhen è simile a MapWhen, ma la diramazione si ricongiunge alla pipeline principale al termine dell'elaborazione. In questo modo è possibile aggiungere middleware condizionalmente senza creare una biforcazione permanente.

// Log only for authenticated API calls; public routes not logged
app.UseWhen(
    ctx => ctx.Request.Path.StartsWithSegments("/api")
           && ctx.User.Identity?.IsAuthenticated == true,
    loggedApp =>
    {
        loggedApp.UseMiddleware<AuditMiddleware>();
    });

// All requests continue here after the branch
app.UseRouting();
app.MapControllers();

Interruzione anticipata senza chiamare Next

Qualsiasi middleware può interrompere anticipatamente la pipeline scrivendo la risposta e non chiamando next. L'elaborazione si interrompe in quel punto e la risposta viene restituita al client.

app.Use(async (ctx, next) =>
{
    // IP allowlist check
    var ip = ctx.Connection.RemoteIpAddress?.ToString();
    var allowed = new[] { "127.0.0.1", "::1", "10.0.0.0/8" };

    if (!IsAllowed(ip, allowed))
    {
        ctx.Response.StatusCode = 403;
        await ctx.Response.WriteAsJsonAsync(
            new { error = "Access denied from this IP" });
        return; // short-circuit
    }

    await next(ctx); // proceed
});

ShortCircuit() in .NET 8

In .NET 8, MapShortCircuit e l'estensione ShortCircuit() sugli endpoint forniscono un percorso dichiarativo e altamente ottimizzato per l'interruzione anticipata.

// Reject known bad paths immediately — skip entire pipeline
app.MapShortCircuit(404, "robots.txt", "favicon.ico");

// Or on a specific endpoint:
app.MapGet("/health", () => "OK")
   .ShortCircuit(); // skips auth, rate limiting, etc.

// 'Run' middleware also short-circuits:
app.Map("/old-api", old =>
    old.Run(ctx =>
    {
        ctx.Response.StatusCode = 301;
        ctx.Response.Headers.Location = "/api/v2";
        return Task.CompletedTask;
    }));

Middleware terminale e routing degli endpoint

Prima di .NET 3, app.Run() era l'unica opzione terminale. Ora è preferibile il routing degli endpoint, tramite MapGet e MapControllers, perché partecipa all'autorizzazione, alla limitazione della frequenza e alla gestione dei metadati.

// OLD: terminal middleware
app.Run(async ctx => {
    if (ctx.Request.Path == "/ping")
        await ctx.Response.WriteAsync("pong");
});

// PREFERRED: endpoint routing
app.MapGet("/ping", () => "pong")
   .WithTags("Health")
   .AllowAnonymous()
   .RequireRateLimiting("basic");

Particolarità della corrispondenza dei percorsi

Map("/api") corrisponde a /api e /api/anything. Il percorso corrispondente viene rimosso da Request.Path all'interno della diramazione e inserito in Request.PathBase.

app.Map("/api", apiApp =>
{
    apiApp.Use(async (ctx, next) =>
    {
        // Path in branch: /users/42 (prefix removed)
        Console.WriteLine(ctx.Request.Path);     // /users/42
        Console.WriteLine(ctx.Request.PathBase); // /api
        await next(ctx);
    });
    apiApp.MapGet("/users/{id}", (int id) => id);
});

Combinare i modelli di diramazione

Le app reali combinano Map, UseWhen e le interruzioni anticipate per creare pipeline stratificate: i percorsi pubblici sono leggeri, quelli delle API includono l'autenticazione e quelli amministrativi prevedono controlli aggiuntivi.

// Public area — no auth
app.Map("/public", pub =>
{
    pub.MapGet("/health", () => "OK");
    pub.MapGet("/docs",   () => "Documentation");
});

// API area — full auth + rate limiting
app.Map("/api", api =>
{
    api.UseAuthentication();
    api.UseAuthorization();
    api.UseRateLimiter();
    api.MapControllers();
});

// Admin area — require admin role
app.Map("/admin", admin =>
{
    admin.UseAuthentication();
    admin.UseAuthorization();
    admin.MapControllers().RequireAuthorization("AdminPolicy");
});

Caso reale: middleware per i test A/B

Un middleware per i test A/B indirizza le richieste verso gestori diversi in base a un cookie o a un'intestazione, senza modificare il codice degli endpoint.

app.UseWhen(
    ctx => ctx.Request.Cookies.TryGetValue("ab-group", out var g) && g == "B",
    betaApp =>
    {
        betaApp.Use(async (ctx, next) =>
        {
            ctx.Items["IsGroupB"] = true;
            await next(ctx);
        });
    });

// Endpoint reads the flag:
app.MapGet("/products", (HttpContext ctx, ProductService svc) =>
{
    bool isB = ctx.Items.ContainsKey("IsGroupB");
    return isB ? svc.GetNewLayoutAsync() : svc.GetOldLayoutAsync();
});

Verifica rapida

Qual è la differenza fondamentale tra MapWhen e UseWhen?

Riepilogo: interruzione anticipata e diramazione

Punti chiave:

  • Map: diramazione permanente basata sul percorso, senza ricongiungimento
  • MapWhen: diramazione permanente basata su un predicato
  • UseWhen: diramazione condizionale che si ricongiunge alla pipeline principale
  • Interruzione anticipata: non chiami next, scrivi la risposta e restituisci il controllo
  • ShortCircuit() (.NET 8): endpoint terminali dichiarativi e ottimizzati
  • Combini le diramazioni per creare pipeline stratificate: pubblica, API e amministrativa

Domande Frequenti

La lezione «Interruzione anticipata e ramificazione» è gratuita?

Sì — il testo completo di «Interruzione anticipata e ramificazione» è 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 «Interruzione anticipata e ramificazione»?

Usi MapWhen, UseWhen e middleware terminali per diramare o terminare la pipeline in base alle condizioni della richiesta. 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 3 di 4.

Quanto tempo richiede la lezione «Interruzione anticipata e ramificazione»?

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

  1. Panoramica della pipeline di ASP.NET Core
  2. Scrittura di middleware personalizzati
  3. Interruzione anticipata e ramificazione
  4. Ordine dei middleware e middleware integrati
← Torna a C# Academy