C# Academy · Lektion

Kortslutning og forgrening

Brug MapWhen, UseWhen og terminal middleware til at forgrene eller afslutte pipelinen baseret på anmodningens betingelser.

Lektion 3 af 412 trin

Kortslutning og forgrening er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.

Forgrening og afkortning

Det er ikke alle anmodninger, der skal gennemløbe hele middleware-kæden. ASP.NET Core indeholder værktøjer til at forgrene den, så delmængder sendes til andre kæder, og til at afkorte den, så behandlingen stoppes og der returneres med det samme.

Map: Permanent forgrening efter sti

Map opretter en permanent forgrening — anmodninger, der matcher præfikset, går ind i grenen og vender ALDRIG tilbage til hovedkæden.

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: Forgrening efter prædikat

MapWhen forgrener baseret på en vilkårlig betingelse, f.eks. headere, forespørgselsparametre eller brugerdefineret logik. Ligesom med Map er grenen permanent — den slutter sig ikke til hovedkæden igen.

// 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: Betinget forgrening, der slutter sig til kæden igen

UseWhen minder om MapWhen, men grenen slutter sig til hovedkæden igen, når den er færdig. Det gør det muligt at tilføje middleware betinget uden at opdele kæden.

// 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();

Afkortning ved ikke at kalde Next

Al middleware kan afkorte kæden ved at skrive svaret uden at kalde next. Kæden stopper på det punkt, og svaret returneres til klienten.

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() i .NET 8

I .NET 8 giver MapShortCircuit og udvidelsen ShortCircuit() på endpoints en deklarativ og stærkt optimeret vej til at afkorte kæden.

// 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;
    }));

Afsluttende middleware kontra endpoint-routing

Før .NET 3 var app.Run() den eneste mulighed for at afslutte kæden. Nu foretrækkes endpoint-routing (MapGet, MapControllers) — den integreres med autorisation, hastighedsbegrænsning og metadata.

// 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");

Nuancer ved matchning af stier

Map("/api") matcher /api og /api/anything. Den matchede sti fjernes fra Request.Path i grenen og placeres i 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);
});

Kombination af forgreningsmønstre

Virkelige apps kombinerer Map, UseWhen og afkortninger for at oprette lagdelte kæder: offentlige ruter er lette, API-ruter har godkendelse, og administratorruter har ekstra kontroller.

// 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");
});

I praksis: A/B-testmiddleware

A/B-testmiddleware forgrener anmodninger til forskellige behandlere baseret på en cookie eller en header uden at ændre endpoint-koden.

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();
});

Hurtigt tjek

Hvad er den vigtigste forskel på MapWhen og UseWhen?

Opsummering: Afkortning og forgrening

Vigtigste pointer:

  • Map: permanent sti-baseret forgrening uden at slutte sig til hovedkæden igen
  • MapWhen: permanent prædikatbaseret forgrening
  • UseWhen: betinget forgrening, der slutter sig til hovedkæden igen
  • Afkortning: kald ikke next, skriv svaret, og returnér
  • ShortCircuit() (.NET 8): deklarative, optimerede afsluttende endpoints
  • Kombinér forgreninger for at bygge lagdelte kæder: offentlige ruter / API-ruter / administratorruter
Gratis at komme i gang

Lær C# med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
93
Lektioner
346

Ofte stillede spørgsmål

Er lektionen “Kortslutning og forgrening” gratis?

Ja — hele teksten til “Kortslutning og forgrening” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Kortslutning og forgrening”?

Brug MapWhen, UseWhen og terminal middleware til at forgrene eller afslutte pipelinen baseret på anmodningens betingelser. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på C# Academy?

Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Kortslutning og forgrening”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne C# Academy-lektion?

Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Oversigt over ASP.NET Core-pipelinen
  2. Skriv brugerdefineret middleware
  3. Kortslutning og forgrening
  4. Middleware-rækkefølge og indbygget middleware
← Tilbage til C# Academy