Delen via


ASP.NET Core Middleware

Notitie

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

Door Rick Anderson en Steve Smith

Middleware is software dat wordt geïntegreerd in een applicatiepijplijn om verzoeken en antwoorden af te handelen. Elk onderdeel:

  • Hiermee kiest u of u de aanvraag wilt doorgeven aan het volgende onderdeel in de pijplijn.
  • Kan werk uitvoeren voor en na het volgende onderdeel in de pijplijn.

Aanvraagdelegen worden gebruikt om de aanvraagpijplijn te bouwen. De aanvraagdelegen verwerken elke HTTP-aanvraag.

Requestafgevaardigden worden geconfigureerd met behulp van Run, Mapen de Use extensiemethoden. Een afzonderlijke verzoekgedelegeerde kan inline worden opgegeven als een anonieme methode, in-line middleware, of deze kan worden gedefinieerd in een herbruikbare klasse. Deze herbruikbare klassen en inline anonieme methoden zijn middleware, ook wel middlewareonderdelengenoemd. Elk middlewareonderdeel in de aanvraagpijplijn is verantwoordelijk voor het aanroepen van het volgende onderdeel in de pijplijn of het kortsluiten van de pijplijn. Wanneer een middleware kortgesloten wordt, wordt het een terminal middleware genoemd, omdat het verhindert dat verdere middleware de aanvraag verwerkt.

HTTP-handlers en -modules migreren naar ASP.NET Core middleware legt het verschil tussen aanvraagpijplijnen in ASP.NET Core en ASP.NET 4.x uit en biedt extra middlewarevoorbeelden.

De rol van middleware per app-type

Blazor Web App's, Razor-pagina's en MVC verwerken browserverzoeken op de server met middleware. De richtlijnen in dit artikel zijn van toepassing op deze typen apps.

Zelfstandige Blazor WebAssembly-apps worden volledig uitgevoerd op de client en verwerken geen aanvragen met een middleware-pijplijn. De richtlijnen in dit artikel zijn niet van toepassing op zelfstandige Blazor WebAssembly apps.

Middleware-codeanalyse

ASP.NET Core bevat veel compilerplatformanalyses die toepassingscode controleren op kwaliteit. Zie Code-analyse in ASP.NET Core-apps voor meer informatie

Een middleware-pijplijn maken met WebApplication

De ASP.NET Core-aanvraagpijplijn bestaat uit een reeks verzoekafgevaardigden, die achtereenvolgens worden aangeroepen. In het volgende diagram ziet u het concept. Het uitvoeringspad volgt de zwarte pijlen.

aanvraagverwerkingspatroon met een aanvraag die binnenkomt, verwerkt via drie middlewares en het antwoord dat de app verlaat. Elke middleware voert de logica uit en geeft de aanvraag door aan de volgende middleware bij de volgende() instructie. Nadat de derde middleware de aanvraag verwerkt, wordt de aanvraag teruggegeven via de vorige twee middlewares in omgekeerde volgorde voor extra verwerking na de volgende() instructies voordat de app als reactie op de client wordt verlaten.

Elke gemachtigde kan bewerkingen uitvoeren voor en na de volgende gemachtigde. Gedelegeerden voor het afhandelen van uitzonderingen moeten vroeg in de pijplijn worden aangeroepen, zodat ze uitzonderingen kunnen ondervangen die zich in latere fasen van de pijplijn voordoen.

De eenvoudigst mogelijke ASP.NET Core-app stelt een enkele verzoekafgevaardigde in die alle verzoeken afhandelt. In dit geval is er geen daadwerkelijke aanvraagpijplijn aanwezig. In plaats daarvan wordt één anonieme functie aangeroepen als reactie op elke HTTP-aanvraag.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run();

Koppel meerdere verzoekafgevaardigden aan elkaar met Use. De parameter next vertegenwoordigt de volgende gemachtigde in de pijplijn. U kunt de pijplijn kortsluiten door niet de parameter next aanroepen. Doorgaans kunt u acties uitvoeren vóór en na de next gedelegeerde, zoals in het volgende voorbeeld wordt gedemonstreerde:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    // Do work that can write to the Response.
    await next.Invoke();
    // Do logging or other work that doesn't write to the Response.
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

app.Run();

Kortsluiting van de aanvraagpijplijn

Wanneer een gemachtigde een aanvraag niet doorgeeft aan de volgende gemachtigde, heet dat het verzoekenpijplijn omzeilen. Kortsluiting is vaak wenselijk omdat het onnodig werk vermijdt. Static File Middleware- kan bijvoorbeeld fungeren als een terminal-middleware door een aanvraag voor een statisch bestand te verwerken en de rest van de pijplijn kortsluiten. Middleware toegevoegd aan de pijplijn vóór de middleware die verdere verwerking beëindigt, blijft code verwerken na hun next.Invoke instructies. Zie echter de volgende waarschuwing over het proberen te schrijven naar een antwoord dat al is verzonden.

Waarschuwing

Roep next.Invoke niet aan tijdens of nadat het antwoord naar de client is verzonden. Nadat een HttpResponse is gestart, resulteren wijzigingen in een uitzondering. bijvoorbeeld headers instellen en een statuscode genereert een uitzondering nadat het antwoord is gestart. Schrijven naar het antwoordlichaam na het aanroepen van next:

  • Kan leiden tot een schending van een protocol, zoals het schrijven van meer dan de vermelde Content-Length.
  • Kan de hoofdtekstindeling beschadigen, zoals het schrijven van een HTML-voettekst naar een CSS-bestand.

HasStarted is een nuttige aanwijzing om aan te geven of er headers zijn verzonden of naar de inhoud is geschreven.

Zie Short-circuit middleware na routeringvoor meer informatie.

Run vertegenwoordigers

Run afgevaardigden ontvangen geen next parameter. De eerste Run gedelegeerde is altijd terminal en beëindigt de pijplijn. Run is een conventie. Sommige middlewareonderdelen kunnen Run[Middleware] methoden beschikbaar maken die aan het einde van de pijplijn worden uitgevoerd:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    // Do work that can write to the Response.
    await next.Invoke();
    // Do logging or other work that doesn't write to the Response.
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

app.Run();

Als u codeopmerkingen wilt zien die zijn vertaald naar andere talen dan Engels, laat het ons dan weten in dit GitHub-discussieprobleem.

In het vorige voorbeeld schrijft de Run delegate "Hello from 2nd delegate." naar de respons en beëindigt de pijplijn. Als er een andere Use of Run delegate wordt toegevoegd na de Run delegate, wordt deze niet aangeroepen.

Geef de voorkeur aan app. Gebruik overbelasting waarvoor de context moet worden doorgegeven aan de volgende

De niet-toewijzende app.Use-extensiemethode

  • Hiervoor moet de context worden doorgegeven aan next.
  • Hiermee worden twee interne toewijzingen per aanvraag bespaard die vereist zijn bij het gebruik van de andere overload-optie.

Zie dit GitHub-probleemvoor meer informatie.

Middleware-volgorde

In het volgende diagram ziet u de volledige pijplijn voor het verwerken van aanvragen voor ASP.NET Core MVC en Razor Pages-apps. U kunt zien hoe in een typische app bestaande middlewares worden geordend en waar aangepaste middlewares worden toegevoegd. U hebt volledige controle over het opnieuw ordenen van bestaande middlewares of het invoeren van nieuwe aangepaste middlewares, indien nodig voor uw scenario's.

ASP.NET Core middleware-pijplijn

De Endpoint middleware in het voorgaande diagram voert de filterpijplijn uit voor het bijbehorende app-type: MVC of Razor Pages.

De Routing middleware in het voorgaande diagram wordt weergegeven achter Static Files. Dit is de volgorde waarin de projectsjablonen worden geïmplementeerd door expliciet app.UseRoutingaan te roepen. Als u app.UseRoutingniet aanroept, wordt de Routing middleware standaard uitgevoerd aan het begin van de pijplijn. Zie Routingvoor meer informatie.

ASP.NET Core-filterpijplijn

De volgorde waarin middlewareonderdelen worden toegevoegd aan het Program.cs-bestand, definieert de volgorde waarin de middleware-onderdelen worden aangeroepen op aanvragen en de omgekeerde volgorde voor het antwoord. De volgorde is kritieke voor beveiliging, prestaties en functionaliteit.

De volgende gemarkeerde code in Program.cs voegt beveiligingsgerelateerde middlewareonderdelen toe in de gebruikelijke aanbevolen volgorde:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMiddleware.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
    ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
// app.UseCookiePolicy();

app.UseRouting();
// app.UseRateLimiter();
// app.UseRequestLocalization();
// app.UseCors();

app.UseAuthentication();
app.UseAuthorization();
// app.UseSession();
// app.UseResponseCompression();
// app.UseResponseCaching();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

In de voorgaande code:

  • Middleware die niet wordt toegevoegd bij het maken van een nieuwe web-app met afzonderlijke gebruikersaccounts wordt uitgecommentarieerd.
  • Niet elke middleware wordt in deze exacte volgorde weergegeven, maar veel wel. Bijvoorbeeld:
    • UseCors, UseAuthenticationen UseAuthorization moeten worden weergegeven in de weergegeven volgorde.
    • UseCors moet momenteel eerst komen voordat UseResponseCaching. Deze vereiste wordt uitgelegd in probleem dotnet/aspnetcore #23218van GitHub.
    • UseRequestLocalization moet vóór middleware staan die de aanvraagcultuur kan controleren, bijvoorbeeld app.UseStaticFiles().
    • UseRateLimiter moet worden aangeroepen na UseRouting wanneer eindpuntspecifieke API's voor frequentiebeperking worden gebruikt. Als het kenmerk [EnableRateLimiting] bijvoorbeeld wordt gebruikt, moet UseRateLimiter worden aangeroepen na UseRouting. Wanneer u alleen globale begrenzers aanroept, kan UseRateLimiter worden aangeroepen voordat UseRouting.

In sommige scenario's heeft middleware een andere volgorde. Caching en compressievolgorde zijn bijvoorbeeld scenariospecifiek en er zijn meerdere geldige volgordes. Bijvoorbeeld:

app.UseResponseCaching();
app.UseResponseCompression();

Met de voorgaande code kan het CPU-gebruik worden verminderd door het gecomprimeerde antwoord in de cache te plaatsen, maar u kunt uiteindelijk meerdere weergaven van een resource opslaan met behulp van verschillende compressiealgoritmen zoals Gzip of Brotli.

In de volgende volgorde worden statische bestanden gecombineerd om gecomprimeerde statische bestanden in de cache toe te staan:

app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();

Met de volgende Program.cs code worden middlewareonderdelen toegevoegd voor veelvoorkomende app-scenario's:

  1. Afhandeling van uitzonderingen/fouten
    • Wanneer de app wordt uitgevoerd in de ontwikkelomgeving:
    • Wanneer de app wordt uitgevoerd in de productieomgeving:
      • Uitzonderingshandler Middleware (UseExceptionHandler) ontvangt uitzonderingen die worden geworpen in de volgende middleware.
      • Met HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) wordt de Strict-Transport-Security-header toegevoegd.
  2. HTTPS Redirection Middleware (UseHttpsRedirection) leidt HTTP-aanvragen om naar HTTPS.
  3. Static File Middleware (UseStaticFiles) levert statische bestanden en onderbreekt verdere verwerking van verzoeken.
  4. Cookie Policy Middleware (UseCookiePolicy) voldoet aan de app aan de AVG-regelgeving (General Data Protection Regulation) van de EU.
  5. Routing Middleware (UseRouting) om aanvragen te routeren.
  6. Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang hebben tot beveiligde resources.
  7. Met Authorization Middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
  8. Session Middleware (UseSession) brengt de sessiestatus tot stand en onderhoudt deze. Als de app de sessiestatus gebruikt, roept u Session Middleware aan na Cookie Policy Middleware en voor MVC Middleware.
  9. Endpoint Routing Middleware (UseEndpoints met MapRazorPages) om Razor Pages-eindpunten toe te voegen aan de verzoekpipeline.
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.MapRazorPages();

In de voorgaande voorbeeldcode wordt elke middleware-extensiemethode weergegeven op WebApplicationBuilder via de Microsoft.AspNetCore.Builder naamruimte.

UseExceptionHandler is het eerste middlewareonderdeel dat aan de pijplijn is toegevoegd. De Uitzonderingshandler Middleware onderschept daarom eventuele uitzonderingen die optreden in latere aanroepen.

Static File Middleware wordt vroeg in de pijplijn aangeroepen, zodat het aanvragen kan afhandelen en de resterende onderdelen kan omzeilen. De Static File Middleware biedt geen autorisatiecontroles. Alle bestanden die worden geleverd door Static File Middleware, waaronder bestanden onder wwwroot, zijn openbaar beschikbaar. Zie Statische bestanden in ASP.NET Corevoor een benadering voor het beveiligen van statische bestanden.

Als de aanvraag niet wordt verwerkt door de Static File Middleware, wordt deze doorgegeven aan de verificatie-middleware (UseAuthentication), waarmee verificatie wordt uitgevoerd. Authenticatie omzeilt geen niet-geauthenticeerde verzoeken. Hoewel verificatie-middleware aanvragen verifieert, vindt autorisatie (en afwijzing) alleen plaats nadat MVC een specifieke Razor Pagina of MVC-controller en -actie selecteert.

In het volgende voorbeeld ziet u een middlewarevolgorde waarin aanvragen voor statische bestanden worden verwerkt door Static File Middleware vóór Response Compression Middleware. Statische bestanden worden niet gecomprimeerd met deze middlewarevolgorde. De reacties van de Razor-pagina kunnen worden gecomprimeerd.

// Static files aren't compressed by Static File Middleware.
app.UseStaticFiles();

app.UseRouting();

app.UseResponseCompression();

app.MapRazorPages();

Zie Overzicht van SPA's (Single Page Apps) in ASP.NET Corevoor meer informatie over toepassingen met één pagina.

Volgorde van UseCors en UseStaticFiles

De volgorde voor het aanroepen van UseCors en UseStaticFiles is afhankelijk van de app. Zie UseCors- en UseStaticFiles-volgorde voor meer informatie

Doorgestuurde headers volgorde van de middleware

Doorgeschakelde headers-middleware moet draaien voordat andere middleware draait. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. Zie Forwarded Headers Middlewareom het [Forwarded Headers Middleware] uit te voeren na de middleware voor diagnosticeren en fouten afhandelen.

De middleware-pijplijn vertakken

Map extensies worden gebruikt als een conventie voor het vertakken van de pijplijn. Map splitst de aanvraagpijplijn op basis van overeenkomende elementen van het opgegeven aanvraagpad. Als het aanvraagpad begint met het opgegeven pad, wordt de vertakking uitgevoerd.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/map1", HandleMapTest1);

app.Map("/map2", HandleMapTest2);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleMapTest1(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 1");
    });
}

static void HandleMapTest2(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 2");
    });
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de voorgaande code.

Verzoek Antwoord
localhost:1234 Hallo vanuit de niet-Map-gedelegeerde.
localhost:1234/map1 Kaarttest 1
localhost:1234/map2 Kaarttest 2
localhost:1234/map3 Hallo vanuit de niet-Map-gedelegeerde.

Wanneer Map wordt gebruikt, worden de overeenkomende padsegmenten verwijderd uit HttpRequest.Path en toegevoegd aan HttpRequest.PathBase voor elke aanvraag.

Map ondersteunt nesten, bijvoorbeeld:

app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

Map kan ook meerdere segmenten tegelijk overeenkomen:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/map1/seg1", HandleMultiSeg);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleMultiSeg(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 1");
    });
}

MapWhen vertakt de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. Elk predicaat van het type Func<HttpContext, bool> kan worden gebruikt om aanvragen toe te wijzen aan een nieuwe vertakking van de pijplijn. In het volgende voorbeeld wordt een predicaat gebruikt om de aanwezigheid van een queryreeksvariabele te detecteren branch:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapWhen(context => context.Request.Query.ContainsKey("branch"), HandleBranch);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleBranch(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        var branchVer = context.Request.Query["branch"];
        await context.Response.WriteAsync($"Branch used = {branchVer}");
    });
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de vorige code:

Verzoek Antwoord
localhost:1234 Hello from non-Map delegate.
localhost:1234/?branch=main Branch used = main

UseWhen vertakt ook de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. In tegenstelling tot MapWhenwordt deze tak opnieuw aan de hoofdleiding aangesloten als deze geen terminal-middleware bevat.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseWhen(context => context.Request.Query.ContainsKey("branch"),
    appBuilder => HandleBranchAndRejoin(appBuilder));

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

void HandleBranchAndRejoin(IApplicationBuilder app)
{
    var logger = app.ApplicationServices.GetRequiredService<ILogger<Program>>(); 

    app.Use(async (context, next) =>
    {
        var branchVer = context.Request.Query["branch"];
        logger.LogInformation("Branch used = {branchVer}", branchVer);

        // Do work that doesn't write to the Response.
        await next();
        // Do other work that doesn't write to the Response.
    });
}

In het voorgaande voorbeeld wordt een antwoord van Hello from non-Map delegate. geschreven voor alle aanvragen. Als de aanvraag een queryreeksvariabele bevat branch, wordt de waarde vastgelegd voordat de hoofdpijplijn opnieuw wordt toegevoegd.

Ingebouwde middleware

ASP.NET Core wordt geleverd met de volgende middlewareonderdelen. De kolom Order bevat notities over middlewareplaatsing in de pijplijn voor aanvraagverwerking en onder welke voorwaarden de middleware de verwerking van aanvragen kan beëindigen. Wanneer een middleware de aanvraagverwerkingspijplijn kortcircuitt en voorkomt dat verdere downstream-middleware een aanvraag verwerkt, wordt dit een terminal-middlewaregenoemd. Zie de sectie Een middleware-pijplijn maken met WebApplication voor meer informatie over kortsluiting.

Middleware Beschrijving Bevelen
verificatie Biedt ondersteuning voor verificatie. Voordat HttpContext.User nodig is. Terminal voor OAuth-callbacks.
autorisatie Biedt autorisatieondersteuning. Direct na de authenticatie-middleware.
Cookie Beleid Houdt toestemming van gebruikers bij voor het opslaan van persoonlijke gegevens en dwingt minimumstandaarden af voor cookie velden, zoals secure en SameSite. Voordat de middleware cookies uitgeeft. Voorbeelden: verificatie, sessie, MVC (TempData).
CORS Hiermee wordt Cross-Origin Resource Sharing geconfigureerd. Voordat onderdelen CORS gebruiken. UseCors moet momenteel vóór UseResponseCaching gaan vanwege fout .
DeveloperExceptionPage Hiermee wordt een pagina gegenereerd met foutinformatie die alleen is bedoeld voor gebruik in de ontwikkelomgeving. Voordat onderdelen fouten genereren. De projectsjablonen registreren deze middleware automatisch als de eerste middleware in de pijplijn wanneer de omgeving op Ontwikkeling staat.
Diagnostische gegevens Verschillende afzonderlijke middlewares die een uitzonderingspagina voor ontwikkelaars bieden, uitzonderingsafhandeling, statuscodepagina's en de standaardwebpagina voor nieuwe apps. Voordat de onderdelen fouten beginnen te genereren. Terminal voor uitzonderingen of het leveren van de standaardwebpagina voor nieuwe apps.
Doorgestuurde Headers Hiermee worden via een proxy ontvangen headers doorgestuurd naar het huidige verzoek. Voordat componenten de bijgewerkte velden gebruiken. Voorbeelden: schema, host, client-IP, methode.
gezondheidscontrole Controleert de status van een ASP.NET Core-app en de bijbehorende afhankelijkheden, zoals het controleren van de beschikbaarheid van de database. Terminal als een aanvraag overeenkomt met een statuscontrole-eindpunt.
Doorgifte van Kopteksten Hiermee worden HTTP-headers van de binnenkomende aanvraag doorgegeven aan de uitgaande HTTP-clientaanvragen.
HTTP-logboekregistratie Registreert HTTP-aanvragen en -antwoorden. Aan het begin van de middleware-pijplijn.
HTTP-methode overschrijven Hiermee kan een binnenkomende POST-aanvraag de methode overschrijven. Voordat onderdelen de bijgewerkte methode gebruiken.
HTTPS-omleiding Alle HTTP-aanvragen omleiden naar HTTPS. Voordat onderdelen de URL gebruiken.
HTTP Strict Transport Security (HSTS) Middleware voor beveiligingsverbeteringen waarmee een speciale antwoordheader wordt toegevoegd. Voordat de antwoorden worden verzonden, en nadat de onderdelen de aanvragen hebben gewijzigd. Voorbeelden: Doorgestuurde headers, URL-herschrijven.
MVC Verwerkt aanvragen met MVC/Razor Pages. Terminal als een aanvraag overeenkomt met een route.
OWIN Interoperabiliteit met op OWIN gebaseerde apps, servers en middleware. Terminal als de OWIN Middleware de aanvraag volledig verwerkt.
Cache voor uitvoer Biedt ondersteuning voor het opslaan van antwoorden in cache op basis van configuratie. Voordat je onderdelen gebruikt die caching vereisen. UseRouting moet vóór UseOutputCachingkomen. UseCORS moet vóór UseOutputCachingkomen.
Response Caching Biedt ondersteuning voor het opslaan van antwoorden in cache. Dit vereist deelname van de cliënt om te werken. Gebruik uitvoercache voor volledig serverbeheer. Voordat je onderdelen gebruikt die caching vereisen. UseCORS moet vóór UseResponseCachingkomen. Is doorgaans niet nuttig voor UI-apps zoals Razor Pagina's, omdat browsers in het algemeen aanvraagheaders instellen die caching voorkomen. Output-caching is voordelig voor UI-apps.
Verzoek tot decompressie Biedt ondersteuning voor het decomprimeren van aanvragen. Voordat componenten de inhoud van de aanvraag lezen.
Antwoordcompressie Biedt ondersteuning voor het comprimeren van antwoorden. Voordat onderdelen compressie vereisen.
Verzoek om lokalisatie Biedt lokalisatieondersteuning. Voordat gevoelige onderdelen worden gelokaliseerd. Moet verschijnen na Routing Middleware bij gebruik van RouteDataRequestCultureProvider.
Time-outs voor verzoeken Biedt ondersteuning voor het configureren van time-outs voor aanvragen, globaal en per eindpunt. UseRequestTimeouts moet na UseExceptionHandler, UseDeveloperExceptionPageen UseRoutingkomen.
eindpuntroutering Hiermee definieert en beperkt u aanvraagroutes. Terminal voor overeenkomende routes.
SPA Verwerkt alle aanvragen vanaf dit punt in de middlewareketen door de standaardpagina voor de toepassing met één pagina (SPA) te retourneren Laat in de keten, zodat andere middleware voor het serveren van statische bestanden, MVC-acties, enz., voorrang krijgt.
sessie Biedt ondersteuning voor het beheren van gebruikerssessies. Voordat onderdelen een sessie vereisen.
statische bestanden Biedt ondersteuning voor het leveren van statische bestanden en bladeren door mappen. Terminal als een aanvraag overeenkomt met een bestand.
URL herschrijven Biedt ondersteuning voor het herschrijven van URL's en het omleiden van aanvragen. Voordat onderdelen de URL gebruiken.
W3CLogging Genereert servertoegangslogboeken in de uitgebreide W3C-logboekindeling. Aan het begin van de middleware-pijplijn.
WebSockets Hiermee schakelt u het WebSockets-protocol in. Voordat noodzakelijke onderdelen WebSocket-verzoeken kunnen accepteren.

Aanvullende informatiebronnen

Door Rick Anderson en Steve Smith

Middleware is software dat wordt geïntegreerd in een applicatiepijplijn om verzoeken en antwoorden af te handelen. Elk onderdeel:

  • Hiermee kiest u of u de aanvraag wilt doorgeven aan het volgende onderdeel in de pijplijn.
  • Kan werk uitvoeren voor en na het volgende onderdeel in de pijplijn.

Aanvraagdelegen worden gebruikt om de aanvraagpijplijn te bouwen. De aanvraagdelegen verwerken elke HTTP-aanvraag.

Requestafgevaardigden worden geconfigureerd met behulp van Run, Mapen de Use extensiemethoden. Een gemachtigde van een afzonderlijke aanvraag kan inline worden opgegeven als een anonieme methode (in-line middleware genoemd) of kan worden gedefinieerd in een herbruikbare klasse. Deze herbruikbare klassen en inline anonieme methoden zijn middleware, ook wel middlewareonderdelengenoemd. Elk middlewareonderdeel in de aanvraagpijplijn is verantwoordelijk voor het aanroepen van het volgende onderdeel in de pijplijn of het kortsluiten van de pijplijn. Wanneer een middleware kortgesloten wordt, wordt het een terminal middleware genoemd, omdat het verhindert dat verdere middleware de aanvraag verwerkt.

HTTP-handlers en -modules migreren naar ASP.NET Core middleware legt het verschil tussen aanvraagpijplijnen in ASP.NET Core en ASP.NET 4.x uit en biedt extra middlewarevoorbeelden.

De rol van middleware per app-type

Razor Pages, MVC, Blazor Serveren het server-side project van een gehoste Blazor WebAssembly oplossing verwerken browseraanvragen op de server met behulp van middleware. De richtlijnen in dit artikel zijn van toepassing op deze typen apps.

Zelfstandige Blazor WebAssembly-apps worden volledig uitgevoerd op de client en verwerken geen aanvragen met een middleware-pijplijn. De richtlijnen in dit artikel zijn niet van toepassing op zelfstandige Blazor WebAssembly apps.

Middleware-codeanalyse

ASP.NET Core bevat veel compilerplatformanalyses die toepassingscode controleren op kwaliteit. Zie Code-analyse in ASP.NET Core-apps voor meer informatie

Een middleware-pijplijn maken met WebApplication

De ASP.NET Core-aanvraagpijplijn bestaat uit een reeks verzoekafgevaardigden, die achtereenvolgens worden aangeroepen. In het volgende diagram ziet u het concept. Het uitvoeringspad volgt de zwarte pijlen.

aanvraagverwerkingspatroon met een aanvraag die binnenkomt, verwerkt via drie middlewares en het antwoord dat de app verlaat. Elke middleware voert de logica uit en geeft de aanvraag door aan de volgende middleware bij de volgende() instructie. Nadat de derde middleware de aanvraag verwerkt, wordt de aanvraag teruggegeven via de vorige twee middlewares in omgekeerde volgorde voor extra verwerking na de volgende() instructies voordat de app als reactie op de client wordt verlaten.

Elke gemachtigde kan bewerkingen uitvoeren voor en na de volgende gemachtigde. Gedelegeerden voor het afhandelen van uitzonderingen moeten vroeg in de pijplijn worden aangeroepen, zodat ze uitzonderingen kunnen ondervangen die zich in latere fasen van de pijplijn voordoen.

De eenvoudigst mogelijke ASP.NET Core-app stelt een enkele verzoekafgevaardigde in die alle verzoeken afhandelt. In dit geval is er geen daadwerkelijke aanvraagpijplijn aanwezig. In plaats daarvan wordt één anonieme functie aangeroepen als reactie op elke HTTP-aanvraag.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run();

Koppel meerdere verzoekafgevaardigden aan elkaar met Use. De parameter next vertegenwoordigt de volgende gemachtigde in de pijplijn. U kunt de pijplijn kortsluiten door niet de parameter next aanroepen. Doorgaans kunt u acties uitvoeren vóór en na de next gedelegeerde, zoals in het volgende voorbeeld wordt gedemonstreerde:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    // Do work that can write to the Response.
    await next.Invoke();
    // Do logging or other work that doesn't write to the Response.
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

app.Run();

Wanneer een gedelegeerde geen aanvraag doorgeeft aan de volgende gedelegeerde, wordt dit het kortsluiten van de aanvraagpijplijn genoemd. Kortsluiting is vaak wenselijk omdat het onnodig werk vermijdt. Bijvoorbeeld, Static File Middleware- kan fungeren als een terminal-middleware door een verzoek voor een statisch bestand te verwerken en de rest van de pijplijn kort te sluiten. Middleware toegevoegd aan de pijplijn vóór de middleware die verdere verwerking beëindigt, blijft code verwerken na hun next.Invoke instructies. Let op de volgende waarschuwing over het proberen te schrijven naar een respons die al is verzonden.

Waarschuwing

Roep next.Invoke niet aan nadat het antwoord naar de client is verzonden. Wijzigingen in HttpResponse nadat het antwoord is gestart, genereert een uitzondering. bijvoorbeeld headers instellen en een statuscode genereert een uitzondering. Schrijven naar het antwoordlichaam na het aanroepen van next:

  • Kan een protocolschending veroorzaken. Bijvoorbeeld meer schrijven dan aangegeven Content-Length.
  • Kan de indeling van de hoofdtekst beschadigen. Bijvoorbeeld het schrijven van een HTML-voettekst naar een CSS-bestand.

HasStarted is een handige hint om aan te geven of er headers zijn verzonden of naar de hoofdtekst is geschreven.

Run afgevaardigden ontvangen geen next parameter. De eerste Run delegaat is altijd terminaal en beëindigt de pijplijn. Run is een conventie. Sommige middlewareonderdelen kunnen Run[Middleware] methoden beschikbaar maken die aan het einde van de pijplijn worden uitgevoerd:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    // Do work that can write to the Response.
    await next.Invoke();
    // Do logging or other work that doesn't write to the Response.
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

app.Run();

Als u codeopmerkingen wilt zien die zijn vertaald naar andere talen dan Engels, laat het ons dan weten in dit GitHub-discussieprobleem.

In het vorige voorbeeld schrijft de Run delegate "Hello from 2nd delegate." naar de respons en beëindigt de pijplijn. Als er een andere Use of Run delegate wordt toegevoegd na de Run delegate, wordt deze niet aangeroepen.

Geef de voorkeur aan app. Gebruik overbelasting waarvoor de context moet worden doorgegeven aan de volgende

De niet-toewijzende app.Use-extensiemethode:

  • Hiervoor moet de context worden doorgegeven aan next.
  • Hiermee worden twee interne toewijzingen per aanvraag bespaard die vereist zijn bij het gebruik van de andere overload-optie.

Zie dit GitHub-probleemvoor meer informatie.

Middleware-volgorde

In het volgende diagram ziet u de volledige pijplijn voor het verwerken van aanvragen voor ASP.NET Core MVC en Razor Pages-apps. U kunt zien hoe in een typische app bestaande middlewares worden geordend en waar aangepaste middlewares worden toegevoegd. U hebt volledige controle over het opnieuw ordenen van bestaande middlewares of het invoeren van nieuwe aangepaste middlewares, indien nodig voor uw scenario's.

ASP.NET Core middleware-pijplijn

De Endpoint middleware in het voorgaande diagram voert de filterpijplijn uit voor het bijbehorende app-type: MVC of Razor Pages.

De Routing middleware in het voorgaande diagram wordt weergegeven achter Static Files. Dit is de volgorde waarin de projectsjablonen worden geïmplementeerd door expliciet app.UseRoutingaan te roepen. Als u app.UseRoutingniet aanroept, wordt de Routing middleware standaard uitgevoerd aan het begin van de pijplijn. Zie Routingvoor meer informatie.

ASP.NET Core-filterpijplijn

De volgorde waarin middlewareonderdelen worden toegevoegd aan het Program.cs-bestand, definieert de volgorde waarin de middleware-onderdelen worden aangeroepen op aanvragen en de omgekeerde volgorde voor het antwoord. De volgorde is kritieke voor beveiliging, prestaties en functionaliteit.

De volgende gemarkeerde code in Program.cs voegt beveiligingsgerelateerde middlewareonderdelen toe in de gebruikelijke aanbevolen volgorde:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMiddleware.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
    ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
// app.UseCookiePolicy();

app.UseRouting();
// app.UseRateLimiter();
// app.UseRequestLocalization();
// app.UseCors();

app.UseAuthentication();
app.UseAuthorization();
// app.UseSession();
// app.UseResponseCompression();
// app.UseResponseCaching();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

In de voorgaande code:

  • Middleware die niet wordt toegevoegd bij het maken van een nieuwe web-app met afzonderlijke gebruikersaccounts wordt uitgecommentarieerd.
  • Niet elke middleware wordt in deze exacte volgorde weergegeven, maar veel wel. Bijvoorbeeld:
    • UseCors, UseAuthenticationen UseAuthorization moeten worden weergegeven in de weergegeven volgorde.
    • UseCors moet momenteel eerst komen voordat UseResponseCaching. Deze vereiste wordt uitgelegd in probleem dotnet/aspnetcore #23218van GitHub.
    • UseRequestLocalization moet vóór middleware staan die de aanvraagcultuur kan controleren, bijvoorbeeld app.UseStaticFiles().
    • UseRateLimiter moet worden aangeroepen na UseRouting wanneer eindpuntspecifieke API's voor frequentiebeperking worden gebruikt. Als het kenmerk [EnableRateLimiting] bijvoorbeeld wordt gebruikt, moet UseRateLimiter worden aangeroepen na UseRouting. Wanneer u alleen globale begrenzers aanroept, kan UseRateLimiter worden aangeroepen voordat UseRouting.

In sommige scenario's heeft middleware een andere volgorde. Caching en compressievolgorde zijn bijvoorbeeld scenariospecifiek en er zijn meerdere geldige volgordes. Bijvoorbeeld:

app.UseResponseCaching();
app.UseResponseCompression();

Met de voorgaande code kan het CPU-gebruik worden verminderd door het gecomprimeerde antwoord in de cache te plaatsen, maar u kunt uiteindelijk meerdere weergaven van een resource opslaan met behulp van verschillende compressiealgoritmen zoals Gzip of Brotli.

In de volgende volgorde worden statische bestanden gecombineerd om gecomprimeerde statische bestanden in de cache toe te staan:

app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();

Met de volgende Program.cs code worden middlewareonderdelen toegevoegd voor veelvoorkomende app-scenario's:

  1. Afhandeling van uitzonderingen/fouten
    • Wanneer de app wordt uitgevoerd in de ontwikkelomgeving:
    • Wanneer de app wordt uitgevoerd in de productieomgeving:
      • Exception Handler Middleware (UseExceptionHandler) vangt uitzonderingen op die worden gegooid in de volgende middlewares.
      • Met HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) wordt de Strict-Transport-Security-header toegevoegd.
  2. HTTPS Redirection Middleware (UseHttpsRedirection) leidt HTTP-aanvragen om naar HTTPS.
  3. Static File Middleware (UseStaticFiles) levert statische bestanden en onderbreekt verdere verwerking van verzoeken.
  4. Cookie Policy Middleware (UseCookiePolicy) voldoet aan de app aan de AVG-regelgeving (General Data Protection Regulation) van de EU.
  5. Routing Middleware (UseRouting) om aanvragen te routeren.
  6. Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang hebben tot beveiligde resources.
  7. Met Authorization Middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
  8. Session Middleware (UseSession) brengt de sessiestatus tot stand en onderhoudt deze. Als de app de sessiestatus gebruikt, roept u Session Middleware aan na Cookie Policy Middleware en voor MVC Middleware.
  9. Endpoint Routing Middleware (UseEndpoints met MapRazorPages) om Razor Pages-eindpunten toe te voegen aan de aanvraagpijplijn.
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.MapRazorPages();

In de voorgaande voorbeeldcode wordt elke middleware-extensiemethode weergegeven op WebApplicationBuilder via de Microsoft.AspNetCore.Builder naamruimte.

UseExceptionHandler is het eerste middlewareonderdeel dat aan de pijplijn is toegevoegd. Daarom vangt de Exception Handling Middleware eventuele uitzonderingen op die zich voordoen bij latere aanroepen.

Static File Middleware wordt vroeg in de pijplijn aangeroepen, zodat het aanvragen kan afhandelen en de resterende onderdelen kan omzeilen. De Static File Middleware biedt geen autorisatiecontroles. Alle bestanden die worden geleverd door Static File Middleware, waaronder bestanden onder wwwroot, zijn openbaar beschikbaar. Zie Statische bestanden in ASP.NET Corevoor een benadering voor het beveiligen van statische bestanden.

Als de aanvraag niet wordt verwerkt door de Static File Middleware, wordt deze doorgegeven aan de verificatie-middleware (UseAuthentication), waarmee verificatie wordt uitgevoerd. Authenticatie omzeilt geen niet-geauthenticeerde verzoeken. Hoewel verificatie-middleware aanvragen verifieert, vindt autorisatie (en afwijzing) alleen plaats nadat MVC een specifieke Razor Pagina of MVC-controller en -actie selecteert.

In het volgende voorbeeld ziet u een middlewarevolgorde waarin aanvragen voor statische bestanden worden verwerkt door Static File Middleware vóór Response Compression Middleware. Statische bestanden worden niet gecomprimeerd met deze middlewarevolgorde. De reacties van de Razor-pagina kunnen worden gecomprimeerd.

// Static files aren't compressed by Static File Middleware.
app.UseStaticFiles();

app.UseRouting();

app.UseResponseCompression();

app.MapRazorPages();

Zie de handleidingen voor de projectsjablonen React en Angular voor informatie over toepassingen met één pagina.

Volgorde van UseCors en UseStaticFiles

De volgorde voor het aanroepen van UseCors en UseStaticFiles is afhankelijk van de app. Zie UseCors- en UseStaticFiles-volgorde voor meer informatie

Doorgestuurde headers volgorde van de middleware

"Forwarded Headers Middleware" moet worden uitgevoerd voordat andere middleware. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. Zie Forwarded Headers Middlewareom het [Forwarded Headers Middleware] uit te voeren na de middleware voor diagnosticeren en fouten afhandelen.

De middleware-pijplijn vertakken

Map extensies worden gebruikt als een conventie voor het vertakken van de pijplijn. Map splitst de aanvraagpijplijn op basis van overeenkomende elementen van het opgegeven aanvraagpad. Als het aanvraagpad begint met het opgegeven pad, wordt de vertakking uitgevoerd.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/map1", HandleMapTest1);

app.Map("/map2", HandleMapTest2);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleMapTest1(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 1");
    });
}

static void HandleMapTest2(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 2");
    });
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de voorgaande code.

Verzoek Antwoord
localhost:1234 Hallo vanuit de niet-Map-gedelegeerde.
localhost:1234/map1 Kaarttest 1
localhost:1234/map2 Kaarttest 2
localhost:1234/map3 Hallo vanuit de niet-Map-gedelegeerde.

Wanneer Map wordt gebruikt, worden de overeenkomende padsegmenten verwijderd uit HttpRequest.Path en toegevoegd aan HttpRequest.PathBase voor elke aanvraag.

Map ondersteunt nesten, bijvoorbeeld:

app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

Map kan ook meerdere segmenten tegelijk overeenkomen:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/map1/seg1", HandleMultiSeg);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleMultiSeg(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 1");
    });
}

MapWhen vertakt de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. Elk predicaat van het type Func<HttpContext, bool> kan worden gebruikt om aanvragen toe te wijzen aan een nieuwe vertakking van de pijplijn. In het volgende voorbeeld wordt een predicaat gebruikt om de aanwezigheid van een queryreeksvariabele te detecteren branch:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapWhen(context => context.Request.Query.ContainsKey("branch"), HandleBranch);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleBranch(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        var branchVer = context.Request.Query["branch"];
        await context.Response.WriteAsync($"Branch used = {branchVer}");
    });
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de vorige code:

Verzoek Antwoord
localhost:1234 Hello from non-Map delegate.
localhost:1234/?branch=main Branch used = main

UseWhen vertakt ook de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. In tegenstelling tot MapWhen, wordt deze vertakking opnieuw aan de hoofdpijplijn gekoppeld als deze niet onderbroken wordt of geen terminal-middleware bevat.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseWhen(context => context.Request.Query.ContainsKey("branch"),
    appBuilder => HandleBranchAndRejoin(appBuilder));

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

void HandleBranchAndRejoin(IApplicationBuilder app)
{
    var logger = app.ApplicationServices.GetRequiredService<ILogger<Program>>(); 

    app.Use(async (context, next) =>
    {
        var branchVer = context.Request.Query["branch"];
        logger.LogInformation("Branch used = {branchVer}", branchVer);

        // Do work that doesn't write to the Response.
        await next();
        // Do other work that doesn't write to the Response.
    });
}

In het voorgaande voorbeeld wordt een antwoord van Hello from non-Map delegate. geschreven voor alle aanvragen. Als de aanvraag een queryreeksvariabele bevat branch, wordt de waarde vastgelegd voordat de hoofdpijplijn opnieuw wordt toegevoegd.

Ingebouwde middleware

ASP.NET Core wordt geleverd met de volgende middlewareonderdelen. De kolom Order bevat notities over middlewareplaatsing in de pijplijn voor aanvraagverwerking en onder welke voorwaarden de middleware de verwerking van aanvragen kan beëindigen. Wanneer een middleware de aanvraagverwerkingspijplijn kortcircuitt en voorkomt dat verdere downstream-middleware een aanvraag verwerkt, wordt dit een terminal-middlewaregenoemd. Zie de sectie Een middleware-pijplijn maken met WebApplication voor meer informatie over kortsluiting.

Middleware Beschrijving Bevelen
verificatie Biedt ondersteuning voor verificatie. Voordat HttpContext.User nodig is. Terminal voor OAuth-callbacks.
autorisatie Biedt autorisatieondersteuning. Direct na de authenticatie-middleware.
Cookie Beleid Houdt toestemming van gebruikers bij voor het opslaan van persoonlijke gegevens en dwingt minimumstandaarden af voor cookie velden, zoals secure en SameSite. Voordat de middleware cookies uitgeeft. Voorbeelden: verificatie, sessie, MVC (TempData).
CORS Hiermee wordt Cross-Origin Resource Sharing geconfigureerd. Voordat onderdelen CORS gebruiken. UseCors moet momenteel vóór UseResponseCaching gaan vanwege fout .
DeveloperExceptionPage Hiermee wordt een pagina gegenereerd met foutinformatie die alleen is bedoeld voor gebruik in de ontwikkelomgeving. Voordat onderdelen fouten beginnen te genereren. De projectsjablonen registreren deze middleware automatisch als de eerste middleware in de pijplijn wanneer de omgeving op Ontwikkeling staat.
Diagnostische gegevens Verschillende afzonderlijke middlewares die een uitzonderingspagina voor ontwikkelaars bieden, uitzonderingsafhandeling, statuscodepagina's en de standaardwebpagina voor nieuwe apps. Voordat onderdelen fouten beginnen te genereren. Terminal voor uitzonderingen of het leveren van de standaardwebpagina voor nieuwe apps.
Doorgestuurde Headers Hiermee worden geproxiede headers doorgestuurd naar de huidige aanvraag. Voordat componenten de bijgewerkte velden gebruiken. Voorbeelden: schema, host, client-IP, methode.
gezondheidscontrole Controleert de status van een ASP.NET Core-app en de bijbehorende afhankelijkheden, zoals het controleren van de beschikbaarheid van de database. Terminal als een aanvraag overeenkomt met een statuscontrole-eindpunt.
Doorgifte van Kopteksten Hiermee worden HTTP-headers van de binnenkomende aanvraag doorgegeven aan de uitgaande HTTP-clientaanvragen.
HTTP-logboekregistratie Registreert HTTP-aanvragen en -antwoorden. Aan het begin van de middleware-pijplijn.
HTTP-methode overschrijven Hiermee kan een binnenkomende POST-aanvraag de methode overschrijven. Voordat onderdelen de bijgewerkte methode gebruiken.
HTTPS-omleiding Alle HTTP-aanvragen omleiden naar HTTPS. Voordat componenten de URL gebruiken.
HTTP Strict Transport Security (HSTS) Middleware voor beveiligingsverbeteringen waarmee een speciale antwoordheader wordt toegevoegd. Voordat de antwoorden worden verzonden, en nadat de onderdelen de aanvragen hebben gewijzigd. Voorbeelden: Doorgestuurde headers, URL-herschrijven.
MVC Verwerkt aanvragen met MVC/Razor Pages. Terminal als een aanvraag overeenkomt met een route.
OWIN Interoperabiliteit met op OWIN gebaseerde apps, servers en middleware. Terminal als de OWIN Middleware de aanvraag volledig verwerkt.
Cache voor uitvoer Biedt ondersteuning voor het opslaan van antwoorden in cache op basis van configuratie. Voordat je onderdelen gebruikt die caching vereisen. UseRouting moet vóór UseOutputCachingkomen. UseCORS moet vóór UseOutputCachingkomen.
voor het opslaan van antwoorden Biedt ondersteuning voor het opslaan van antwoorden in cache. Dit vereist deelname van de cliënt om te werken. Gebruik uitvoercache voor volledig serverbeheer. Voordat je onderdelen gebruikt die caching vereisen. UseCORS moet vóór UseResponseCachingkomen. Is doorgaans niet nuttig voor UI-apps zoals Razor Pagina's, omdat browsers in het algemeen aanvraagheaders instellen die caching voorkomen. Output-caching is voordelig voor UI-apps.
Verzoek tot decompressie Biedt ondersteuning voor het decomprimeren van aanvragen. Voordat componenten de aanvraagtekst lezen.
Antwoordcompressie Biedt ondersteuning voor het comprimeren van antwoorden. Voordat onderdelen moeten worden gecomprimeerd.
Verzoek om lokalisatie Biedt lokalisatieondersteuning. Voordat gevoelige onderdelen worden gelokaliseerd. Moet verschijnen na Routing Middleware bij gebruik van RouteDataRequestCultureProvider.
eindpuntroutering Hiermee definieert en beperkt u aanvraagroutes. Terminal voor overeenkomende routes.
SPA Verwerkt alle aanvragen vanaf dit punt in de middlewareketen door de standaardpagina voor de toepassing met één pagina (SPA) te retourneren Laat in de keten, zodat andere middleware voor het serveren van statische bestanden, MVC-acties, enz., voorrang krijgt.
sessie Biedt ondersteuning voor het beheren van gebruikerssessies. Voordat onderdelen een sessie vereisen.
statische bestanden Biedt ondersteuning voor het leveren van statische bestanden en bladeren door mappen. Terminal als een aanvraag overeenkomt met een bestand.
URL herschrijven Biedt ondersteuning voor het herschrijven van URL's en het omleiden van aanvragen. Voordat onderdelen de URL gebruiken.
W3CLogging Genereert servertoegangslogboeken in de uitgebreide W3C-logboekindeling. Aan het begin van de middleware-pijplijn.
WebSockets Hiermee schakelt u het WebSockets-protocol in. Voordat noodzakelijke onderdelen WebSocket-verzoeken kunnen accepteren.

Aanvullende informatiebronnen

Door Rick Anderson en Steve Smith

Middleware is software dat wordt geïntegreerd in een applicatiepijplijn om verzoeken en antwoorden af te handelen. Elk onderdeel:

  • Hiermee kiest u of u de aanvraag wilt doorgeven aan het volgende onderdeel in de pijplijn.
  • Kan werk uitvoeren voor en na het volgende onderdeel in de pijplijn.

Verzoekafgevaardigden worden gebruikt om de verzoekpijplijn te bouwen. De aanvraagdelegen verwerken elke HTTP-aanvraag.

Requestafgevaardigden worden geconfigureerd met behulp van Run, Mapen de Use extensiemethoden. Een individuele aanvraaggedelegeerde kan inline worden gedefinieerd als een anonieme methode (in-line middleware genoemd) of kan worden gedefinieerd in een herbruikbare klasse. Deze herbruikbare klassen en inline anonieme methoden zijn middleware, ook wel middlewareonderdelengenoemd. Elk middlewareonderdeel in de aanvraagpijplijn is verantwoordelijk voor het aanroepen van het volgende onderdeel in de pijplijn of het kortsluiten van de pijplijn. Wanneer een middleware kortgesloten wordt, wordt het een terminal middleware genoemd, omdat het verhindert dat verdere middleware de aanvraag verwerkt.

HTTP-handlers en -modules migreren naar ASP.NET Core middleware legt het verschil tussen aanvraagpijplijnen in ASP.NET Core en ASP.NET 4.x uit en biedt extra middlewarevoorbeelden.

Middleware-codeanalyse

ASP.NET Core bevat veel compilerplatformanalyses die toepassingscode controleren op kwaliteit. Zie Code-analyse in ASP.NET Core-apps voor meer informatie

Een middleware-pijplijn maken met WebApplication

De ASP.NET Core-aanvraagpijplijn bestaat uit een reeks verzoekafgevaardigden, die achtereenvolgens worden aangeroepen. In het volgende diagram ziet u het concept. Het uitvoeringspad volgt de zwarte pijlen.

aanvraagverwerkingspatroon met een aanvraag die binnenkomt, verwerkt via drie middlewares en het antwoord dat de app verlaat. Elke middleware voert de logica uit en geeft de aanvraag door aan de volgende middleware bij de volgende() instructie. Nadat de derde middleware de aanvraag verwerkt, wordt de aanvraag teruggegeven via de vorige twee middlewares in omgekeerde volgorde voor extra verwerking na de volgende() instructies voordat de app als reactie op de client wordt verlaten.

Elke gemachtigde kan bewerkingen uitvoeren voor en na de volgende gemachtigde. Gedelegeerden voor het afhandelen van uitzonderingen moeten vroeg in de pijplijn worden aangeroepen, zodat ze uitzonderingen kunnen ondervangen die zich in latere fasen van de pijplijn voordoen.

De eenvoudigst mogelijke ASP.NET Core-app stelt een enkele verzoekafgevaardigde in die alle verzoeken afhandelt. In dit geval is er geen daadwerkelijke aanvraagpijplijn aanwezig. In plaats daarvan wordt één anonieme functie aangeroepen als reactie op elke HTTP-aanvraag.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run();

Koppel meerdere verzoekafgevaardigden aan elkaar met Use. De parameter next vertegenwoordigt de volgende gemachtigde in de pijplijn. U kunt de pijplijn kortsluiten door niet de parameter next aanroepen. Doorgaans kunt u acties uitvoeren vóór en na de next gedelegeerde, zoals in het volgende voorbeeld wordt gedemonstreerde:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    // Do work that can write to the Response.
    await next.Invoke();
    // Do logging or other work that doesn't write to the Response.
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

app.Run();

Wanneer een gemachtigde geen aanvraag doorgeeft aan de volgende gemachtigde, wordt dit genoemd het doorbreken van de aanvraagpijplijn. Kortsluiting is vaak wenselijk omdat het onnodig werk vermijdt. Bijvoorbeeld, Static File Middleware- kan fungeren als een terminal-middleware door een aanvraag voor een statisch bestand te verwerken en de rest van de pijplijn kort te sluiten. Middleware toegevoegd aan de pijplijn vóór de middleware die verdere verwerking beëindigt, blijft code verwerken na hun next.Invoke instructies. Zie echter de volgende waarschuwing over proberen te schrijven naar een reactie die al is verstuurd.

Waarschuwing

Roep next.Invoke niet aan nadat het antwoord naar de client is verzonden. Wijzigingen in HttpResponse nadat het antwoord is gestart, genereert een uitzondering. Bijvoorbeeld, het instellen van headers en een statuscode veroorzaakt een uitzondering. Schrijven naar het antwoordlichaam na het aanroepen van next:

  • Kan een protocolschending veroorzaken. Bijvoorbeeld meer schrijven dan wat is vermeld Content-Length.
  • Kan de indeling van de hoofdtekst beschadigen. Bijvoorbeeld het schrijven van een HTML-voettekst naar een CSS-bestand.

HasStarted is een handige hint om aan te geven of er headers zijn verzonden of naar de hoofdtekst is geschreven.

Run afgevaardigden ontvangen geen next parameter. De eerste Run gedelegeerde is altijd terminaal en beëindigt de pijplijn. Run is een conventie. Sommige middlewareonderdelen kunnen Run[Middleware] methoden beschikbaar maken die aan het einde van de pijplijn worden uitgevoerd:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Use(async (context, next) =>
{
    // Do work that can write to the Response.
    await next.Invoke();
    // Do logging or other work that doesn't write to the Response.
});

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from 2nd delegate.");
});

app.Run();

Als u codeopmerkingen wilt zien die zijn vertaald naar andere talen dan Engels, laat het ons dan weten in dit GitHub-discussieprobleem.

In het vorige voorbeeld schrijft de Run delegate "Hello from 2nd delegate." naar de respons en beëindigt de pijplijn. Als er een andere Use of Run delegate wordt toegevoegd na de Run delegate, wordt deze niet aangeroepen.

Geef de voorkeur aan de overbelasting van app.Use die vereist dat de context aan de volgende wordt doorgegeven.

De niet-toewijzende app.Use-extensiemethode:

  • Hiervoor moet de context worden doorgegeven aan next.
  • Hiermee worden twee interne toewijzingen per aanvraag bespaard die vereist zijn bij het gebruik van de andere overload-optie.

Zie dit GitHub-probleemvoor meer informatie.

Middleware-volgorde

In het volgende diagram ziet u de volledige pijplijn voor het verwerken van aanvragen voor ASP.NET Core MVC en Razor Pages-apps. U kunt zien hoe in een typische app bestaande middlewares worden geordend en waar aangepaste middlewares worden toegevoegd. U hebt volledige controle over het opnieuw ordenen van bestaande middlewares of het invoeren van nieuwe aangepaste middlewares, indien nodig voor uw scenario's.

ASP.NET Core middleware-pijplijn

De Endpoint middleware in het voorgaande diagram voert de filterpijplijn uit voor het bijbehorende app-type: MVC of Razor Pages.

De Routing middleware in het voorgaande diagram wordt weergegeven achter Static Files. Dit is de volgorde waarin de projectsjablonen worden geïmplementeerd door expliciet app.UseRoutingaan te roepen. Als u app.UseRoutingniet aanroept, wordt de Routing middleware standaard uitgevoerd aan het begin van de pijplijn. Zie Routingvoor meer informatie.

ASP.NET Core-filterpijplijn

De volgorde waarin middlewareonderdelen worden toegevoegd aan het Program.cs-bestand, definieert de volgorde waarin de middleware-onderdelen worden aangeroepen op aanvragen en de omgekeerde volgorde voor het antwoord. De volgorde is kritieke voor beveiliging, prestaties en functionaliteit.

De volgende gemarkeerde code in Program.cs voegt beveiligingsgerelateerde middlewareonderdelen toe in de gebruikelijke aanbevolen volgorde:

using IndividualAccountsExample.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
// app.UseCookiePolicy();

app.UseRouting();
// app.UseRequestLocalization();
// app.UseCors();

app.UseAuthentication();
app.UseAuthorization();
// app.UseSession();
// app.UseResponseCompression();
// app.UseResponseCaching();

app.MapRazorPages();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

In de voorgaande code:

  • Middleware die niet wordt toegevoegd bij het maken van een nieuwe web-app met afzonderlijke gebruikersaccounts wordt uitgecommentarieerd.
  • Niet elke middleware wordt in deze exacte volgorde weergegeven, maar veel wel. Bijvoorbeeld:
    • UseCors, UseAuthenticationen UseAuthorization moeten worden weergegeven in de weergegeven volgorde.
    • UseCors moet momenteel eerst komen voordat UseResponseCaching. Deze vereiste wordt uitgelegd in probleem dotnet/aspnetcore #23218van GitHub.
    • UseRequestLocalization moet worden weergegeven vóór middleware die de aanvraagcultuur kan controleren (bijvoorbeeld app.UseMvcWithDefaultRoute()).

In sommige scenario's heeft middleware een andere volgorde. Caching en compressievolgorde zijn bijvoorbeeld scenariospecifiek en er zijn meerdere geldige volgordes. Bijvoorbeeld:

app.UseResponseCaching();
app.UseResponseCompression();

Met de voorgaande code kan het CPU-gebruik worden verminderd door het gecomprimeerde antwoord in de cache te plaatsen, maar u kunt uiteindelijk meerdere weergaven van een resource opslaan met behulp van verschillende compressiealgoritmen zoals Gzip of Brotli.

In de volgende volgorde worden statische bestanden gecombineerd om gecomprimeerde statische bestanden in de cache toe te staan:

app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();

Met de volgende Program.cs code worden middlewareonderdelen toegevoegd voor veelvoorkomende app-scenario's:

  1. Afhandeling van uitzonderingen/fouten
    • Wanneer de app wordt uitgevoerd in de ontwikkelomgeving:
    • Wanneer de app wordt uitgevoerd in de productieomgeving:
      • Uitzonderingshandler Middleware (UseExceptionHandler) vangt uitzonderingen op die in de volgende middleware worden gegooid.
      • Met HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) wordt de Strict-Transport-Security-header toegevoegd.
  2. HTTPS Redirection Middleware (UseHttpsRedirection) leidt HTTP-aanvragen om naar HTTPS.
  3. Static File Middleware (UseStaticFiles) levert statische bestanden en onderbreekt verdere verwerking van verzoeken.
  4. Cookie Policy Middleware (UseCookiePolicy) voldoet aan de app aan de AVG-regelgeving (General Data Protection Regulation) van de EU.
  5. Routing Middleware (UseRouting) om aanvragen te routeren.
  6. Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang hebben tot beveiligde resources.
  7. Met Authorization Middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
  8. Session Middleware (UseSession) brengt de sessiestatus tot stand en onderhoudt deze. Als de app de sessiestatus gebruikt, roept u Session Middleware aan na Cookie Policy Middleware en voor MVC Middleware.
  9. Endpoint Routing Middleware (UseEndpoints met MapRazorPages) om de Razor Pages-eindpunten toe te voegen aan de verzoekpijplijn.
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseDatabaseErrorPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.MapRazorPages();

In de voorgaande voorbeeldcode wordt elke middleware-extensiemethode weergegeven op WebApplicationBuilder via de Microsoft.AspNetCore.Builder naamruimte.

UseExceptionHandler is het eerste middlewareonderdeel dat aan de pijplijn is toegevoegd. De Exception Handler Middleware onderschept daarom eventuele uitzonderingen die in latere aanroepen optreden.

Static File Middleware wordt vroeg in de pijplijn aangeroepen, zodat het aanvragen kan afhandelen en de resterende onderdelen kan omzeilen. De Static File Middleware biedt geen autorisatiecontroles. Alle bestanden die worden geleverd door Static File Middleware, waaronder bestanden onder wwwroot, zijn openbaar beschikbaar. Zie Statische bestanden in ASP.NET Corevoor een benadering voor het beveiligen van statische bestanden.

Als de aanvraag niet wordt verwerkt door de Static File Middleware, wordt deze doorgegeven aan de verificatie-middleware (UseAuthentication), waarmee verificatie wordt uitgevoerd. Authenticatie omzeilt geen niet-geauthenticeerde verzoeken. Hoewel verificatie-middleware aanvragen verifieert, vindt autorisatie (en afwijzing) alleen plaats nadat MVC een specifieke Razor Pagina of MVC-controller en -actie selecteert.

In het volgende voorbeeld ziet u een middlewarevolgorde waarin aanvragen voor statische bestanden worden verwerkt door Static File Middleware vóór Response Compression Middleware. Statische bestanden worden niet gecomprimeerd met deze middlewarevolgorde. De reacties van de Razor-pagina kunnen worden gecomprimeerd.

// Static files aren't compressed by Static File Middleware.
app.UseStaticFiles();

app.UseRouting();

app.UseResponseCompression();

app.MapRazorPages();

Zie de handleidingen voor de projectsjablonen React en Angular voor informatie over toepassingen met één pagina.

Volgorde van UseCors en UseStaticFiles

De volgorde voor het aanroepen van UseCors en UseStaticFiles is afhankelijk van de app. Zie UseCors- en UseStaticFiles-volgorde voor meer informatie

Doorgestuurde headers volgorde van de middleware

De doorverwezen headers-middleware moet worden uitgevoerd voordat andere middleware. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. Zie Forwarded Headers Middlewareom het [Forwarded Headers Middleware] uit te voeren na de middleware voor diagnosticeren en fouten afhandelen.

De middleware-pijplijn vertakken

Map extensies worden gebruikt als een standaardmethode voor het vertakken van de pijplijn. Map splitst de aanvraagpijplijn op basis van overeenkomende elementen van het opgegeven aanvraagpad. Als het aanvraagpad begint met het opgegeven pad, wordt de vertakking uitgevoerd.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/map1", HandleMapTest1);

app.Map("/map2", HandleMapTest2);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleMapTest1(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 1");
    });
}

static void HandleMapTest2(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 2");
    });
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de voorgaande code.

Verzoek Antwoord
localhost:1234 Hallo vanuit de niet-Map-gedelegeerde.
localhost:1234/map1 Kaarttest 1
localhost:1234/map2 Kaarttest 2
localhost:1234/map3 Hallo vanuit de niet-Map-gedelegeerde.

Wanneer Map wordt gebruikt, worden de overeenkomende padsegmenten verwijderd uit HttpRequest.Path en toegevoegd aan HttpRequest.PathBase voor elke aanvraag.

Map ondersteunt nesten, bijvoorbeeld:

app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

Map kan ook meerdere segmenten tegelijk overeenkomen:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/map1/seg1", HandleMultiSeg);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleMultiSeg(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Map Test 1");
    });
}

MapWhen vertakt de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. Elk predicaat van het type Func<HttpContext, bool> kan worden gebruikt om aanvragen toe te wijzen aan een nieuwe vertakking van de pijplijn. In het volgende voorbeeld wordt een predicaat gebruikt om de aanwezigheid van een queryreeksvariabele te detecteren branch:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapWhen(context => context.Request.Query.ContainsKey("branch"), HandleBranch);

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

static void HandleBranch(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        var branchVer = context.Request.Query["branch"];
        await context.Response.WriteAsync($"Branch used = {branchVer}");
    });
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de vorige code:

Verzoek Antwoord
localhost:1234 Hello from non-Map delegate.
localhost:1234/?branch=main Branch used = main

UseWhen vertakt ook de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. In tegenstelling tot MapWhen, wordt deze vertakking weer samengevoegd met de hoofdpijplijn als deze geen kortsluiting veroorzaakt noch een terminalmiddleware bevat.

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseWhen(context => context.Request.Query.ContainsKey("branch"),
    appBuilder => HandleBranchAndRejoin(appBuilder));

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello from non-Map delegate.");
});

app.Run();

void HandleBranchAndRejoin(IApplicationBuilder app)
{
    var logger = app.ApplicationServices.GetRequiredService<ILogger<Program>>(); 

    app.Use(async (context, next) =>
    {
        var branchVer = context.Request.Query["branch"];
        logger.LogInformation("Branch used = {branchVer}", branchVer);

        // Do work that doesn't write to the Response.
        await next();
        // Do other work that doesn't write to the Response.
    });
}

In het voorgaande voorbeeld wordt een antwoord van Hello from non-Map delegate. geschreven voor alle aanvragen. Als de aanvraag een queryreeksvariabele bevat branch, wordt de waarde vastgelegd voordat de hoofdpijplijn opnieuw wordt toegevoegd.

Ingebouwde middleware

ASP.NET Core wordt geleverd met de volgende middlewareonderdelen. De kolom Order bevat notities over middlewareplaatsing in de pijplijn voor aanvraagverwerking en onder welke voorwaarden de middleware de verwerking van aanvragen kan beëindigen. Wanneer een middleware de aanvraagverwerkingspijplijn kortcircuitt en voorkomt dat verdere downstream-middleware een aanvraag verwerkt, wordt dit een terminal-middlewaregenoemd. Zie de sectie Een middleware-pijplijn maken met WebApplication voor meer informatie over kortsluiting.

Middleware Beschrijving Bevelen
verificatie Biedt ondersteuning voor verificatie. Voordat HttpContext.User nodig is. Terminal voor OAuth-callbacks.
autorisatie Biedt autorisatieondersteuning. Direct na de authenticatie-middleware.
Cookie Beleid Houdt toestemming van gebruikers bij voor het opslaan van persoonlijke gegevens en dwingt minimumstandaarden af voor cookie velden, zoals secure en SameSite. Voordat de middleware cookies uitgeeft. Voorbeelden: verificatie, sessie, MVC (TempData).
CORS Hiermee wordt Cross-Origin Resource Sharing geconfigureerd. Voordat onderdelen CORS gebruiken. UseCors moet momenteel vóór UseResponseCaching gaan vanwege fout .
DeveloperExceptionPage Hiermee wordt een pagina gegenereerd met foutinformatie die alleen is bedoeld voor gebruik in de ontwikkelomgeving. Voordat onderdelen fouten genereren. De projectsjablonen registreren deze middleware automatisch als de eerste middleware in de pijplijn wanneer de omgeving op Ontwikkeling staat.
Diagnostische gegevens Verschillende afzonderlijke middlewares die een uitzonderingspagina voor ontwikkelaars bieden, uitzonderingsafhandeling, statuscodepagina's en de standaardwebpagina voor nieuwe apps. Voordat onderdelen fouten genereren. Terminal voor uitzonderingen of het leveren van de standaardwebpagina voor nieuwe apps.
Doorgestuurde Headers Hiermee worden geproxydeerde headers naar het huidige verzoek doorgestuurd. Voordat componenten de bijgewerkte velden gebruiken. Voorbeelden: schema, host, client-IP, methode.
gezondheidscontrole Controleert de status van een ASP.NET Core-app en de bijbehorende afhankelijkheden, zoals het controleren van de beschikbaarheid van de database. Terminal als een aanvraag overeenkomt met een statuscontrole-eindpunt.
Doorgifte van Kopteksten Hiermee worden HTTP-headers van de binnenkomende aanvraag doorgegeven aan de uitgaande HTTP-clientaanvragen.
HTTP-logboekregistratie Registreert HTTP-aanvragen en -antwoorden. Aan het begin van de middleware-pijplijn.
HTTP-methode overschrijven Hiermee kan een binnenkomende POST-aanvraag de methode overschrijven. Voordat onderdelen gebruikmaken van de bijgewerkte methode.
HTTPS-omleiding Alle HTTP-aanvragen omleiden naar HTTPS. Voordat onderdelen de URL gebruiken.
HTTP Strict Transport Security (HSTS) Middleware voor beveiligingsverbeteringen waarmee een speciale antwoordheader wordt toegevoegd. Voordat de antwoorden worden verzonden, en nadat de onderdelen de aanvragen hebben gewijzigd. Voorbeelden: Doorgestuurde headers, URL-herschrijven.
MVC Verwerkt aanvragen met MVC/Razor Pages. Terminal als een aanvraag overeenkomt met een route.
OWIN Interoperabiliteit met op OWIN gebaseerde apps, servers en middleware. Terminal als de OWIN Middleware de aanvraag volledig verwerkt.
verzoek decompressie Biedt ondersteuning voor het decomprimeren van aanvragen. Voordat onderdelen de hoofdtekst van de aanvraag lezen.
Response-caching Biedt ondersteuning voor het opslaan van antwoorden in cache. Voordat je onderdelen gebruikt die caching vereisen. UseCORS moet vóór UseResponseCachingkomen.
Antwoordcompressie Biedt ondersteuning voor het comprimeren van antwoorden. Voordat onderdelen compressie vereisen.
Verzoek om lokalisatie Biedt lokalisatieondersteuning. Voordat gevoelige onderdelen worden gelokaliseerd. Moet verschijnen na Routing Middleware bij gebruik van RouteDataRequestCultureProvider.
eindpuntroutering Hiermee definieert en beperkt u aanvraagroutes. Terminal voor overeenkomende routes.
SPA Verwerkt alle aanvragen vanaf dit punt in de middlewareketen door de standaardpagina voor de toepassing met één pagina (SPA) te retourneren Laat in de keten, zodat andere middleware voor het serveren van statische bestanden, MVC-acties, enz., voorrang krijgt.
sessie Biedt ondersteuning voor het beheren van gebruikerssessies. Voordat onderdelen een sessie vereisen.
statische bestanden Biedt ondersteuning voor het leveren van statische bestanden en bladeren door mappen. Terminal als een aanvraag overeenkomt met een bestand.
URL herschrijven Biedt ondersteuning voor het herschrijven van URL's en het omleiden van aanvragen. Voordat onderdelen de URL gebruiken.
W3CLogging Genereert servertoegangslogboeken in de uitgebreide W3C-logboekindeling. Aan het begin van de middleware-pijplijn.
WebSockets Hiermee schakelt u het WebSockets-protocol in. Voordat noodzakelijke onderdelen WebSocket-verzoeken kunnen accepteren.

Aanvullende informatiebronnen

Door Rick Anderson en Steve Smith

Middleware is software dat wordt geïntegreerd in een applicatiepijplijn om verzoeken en antwoorden af te handelen. Elk onderdeel:

  • Hiermee kiest u of u de aanvraag wilt doorgeven aan het volgende onderdeel in de pijplijn.
  • Kan werk uitvoeren voor en na het volgende onderdeel in de pijplijn.

Verzoekafgevaardigden worden gebruikt om de verzoekpijplijn te bouwen. De aanvraagdelegen verwerken elke HTTP-aanvraag.

Requestafgevaardigden worden geconfigureerd met behulp van Run, Mapen de Use extensiemethoden. Een gemachtigde van een afzonderlijke aanvraag kan inline worden opgegeven als een anonieme methode (in-line middleware genoemd) of kan worden gedefinieerd in een herbruikbare klasse. Deze herbruikbare klassen en inline anonieme methoden zijn middleware, ook wel middlewareonderdelengenoemd. Elk middlewareonderdeel in de aanvraagpijplijn is verantwoordelijk voor het aanroepen van het volgende onderdeel in de pijplijn of het kortsluiten van de pijplijn. Wanneer een middleware kortgesloten wordt, wordt het een terminal middleware genoemd, omdat het verhindert dat verdere middleware de aanvraag verwerkt.

HTTP-handlers en -modules migreren naar ASP.NET Core middleware legt het verschil tussen aanvraagpijplijnen in ASP.NET Core en ASP.NET 4.x uit en biedt extra middlewarevoorbeelden.

Een middleware-pijplijn maken met IApplicationBuilder

De ASP.NET Core-aanvraagpijplijn bestaat uit een reeks verzoekafgevaardigden, die achtereenvolgens worden aangeroepen. In het volgende diagram ziet u het concept. Het uitvoeringspad volgt de zwarte pijlen.

aanvraagverwerkingspatroon met een aanvraag die binnenkomt, verwerkt via drie middlewares en het antwoord dat de app verlaat. Elke middleware voert de logica uit en geeft de aanvraag door aan de volgende middleware bij de volgende() instructie. Nadat de derde middleware de aanvraag verwerkt, wordt de aanvraag teruggegeven via de vorige twee middlewares in omgekeerde volgorde voor extra verwerking na de volgende() instructies voordat de app als reactie op de client wordt verlaten.

Elke gemachtigde kan bewerkingen uitvoeren voor en na de volgende gemachtigde. Gedelegeerden voor het afhandelen van uitzonderingen moeten vroeg in de pijplijn worden aangeroepen, zodat ze uitzonderingen kunnen ondervangen die zich in latere fasen van de pijplijn voordoen.

De eenvoudigst mogelijke ASP.NET Core-app stelt een enkele verzoekafgevaardigde in die alle verzoeken afhandelt. In dit geval is er geen daadwerkelijke aanvraagpijplijn aanwezig. In plaats daarvan wordt één anonieme functie aangeroepen als reactie op elke HTTP-aanvraag.

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello, World!");
        });
    }
}

Koppel meerdere verzoekafgevaardigden aan elkaar met Use. De parameter next vertegenwoordigt de volgende gemachtigde in de pijplijn. U kunt de pijplijn kortsluiten door niet de volgende parameter aan te roepen. Doorgaans kunt u acties uitvoeren voor en na de volgende gemachtigde, zoals in het volgende voorbeeld wordt gedemonstreerde:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

Wanneer een verwerker een verzoek niet doorgeeft aan de volgende verwerker, wordt het genoemd het kortsluiten van de verzoekpijplijn. Kortsluiting is vaak wenselijk omdat het onnodig werk vermijdt. Static File Middleware- kan bijvoorbeeld fungeren als een terminal middleware door een verzoek voor een statisch bestand te verwerken en de rest van de pijplijn te omzeilen. Middleware toegevoegd aan de pijplijn vóór de middleware die verdere verwerking beëindigt, blijft code verwerken na hun next.Invoke instructies. Zie echter de volgende waarschuwing over het schrijven naar een antwoord dat al is verzonden.

Waarschuwing

Roep next.Invoke niet aan nadat het antwoord naar de client is verzonden. Wijzigingen in HttpResponse nadat het antwoord is gestart, genereert een uitzondering. bijvoorbeeld het instellen van headers en een statuscode werpen een uitzondering. Schrijven naar het antwoordlichaam na het aanroepen van next:

  • Kan een protocolschending veroorzaken. Bijvoorbeeld meer schrijven dan de vermelde Content-Length.
  • Kan de indeling van de hoofdtekst beschadigen. Bijvoorbeeld het schrijven van een HTML-voettekst naar een CSS-bestand.

HasStarted is een handige hint om aan te geven of er headers zijn verzonden of naar de hoofdtekst is geschreven.

Run afgevaardigden ontvangen geen next parameter. De eerste Run gedelegeerde heeft altijd een terminale functie en beëindigt de pijplijn. Run is een conventie. Sommige middlewareonderdelen kunnen Run[Middleware] methoden beschikbaar maken die aan het einde van de pijplijn worden uitgevoerd:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            // Do work that doesn't write to the Response.
            await next.Invoke();
            // Do logging or other work that doesn't write to the Response.
        });

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from 2nd delegate.");
        });
    }
}

Als u codeopmerkingen wilt zien die zijn vertaald naar andere talen dan Engels, laat het ons dan weten in dit GitHub-discussieprobleem.

In het vorige voorbeeld schrijft de Run delegate "Hello from 2nd delegate." naar de respons en beëindigt de pijplijn. Als er een andere Use of Run delegate wordt toegevoegd na de Run delegate, wordt deze niet aangeroepen.

Middleware-volgorde

In het volgende diagram ziet u de volledige pijplijn voor het verwerken van aanvragen voor ASP.NET Core MVC en Razor Pages-apps. U kunt zien hoe in een typische app bestaande middlewares worden geordend en waar aangepaste middlewares worden toegevoegd. U hebt volledige controle over het opnieuw ordenen van bestaande middlewares of het invoeren van nieuwe aangepaste middlewares, indien nodig voor uw scenario's.

ASP.NET Core middleware-pijplijn

De Endpoint middleware in het voorgaande diagram voert de filterpijplijn uit voor het bijbehorende app-type: MVC of Razor Pages.

ASP.NET Core-filterpijplijn

De volgorde waarin middlewareonderdelen worden toegevoegd in de methode Startup.Configure definieert de volgorde waarin de middleware-onderdelen worden aangeroepen voor aanvragen en de omgekeerde volgorde voor het antwoord. De volgorde is kritieke voor beveiliging, prestaties en functionaliteit.

Met de volgende Startup.Configure methode worden beveiligingsgerelateerde middlewareonderdelen toegevoegd in de gebruikelijke aanbevolen volgorde:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    // app.UseCookiePolicy();

    app.UseRouting();
    // app.UseRequestLocalization();
    // app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();
    // app.UseSession();
    // app.UseResponseCompression();
    // app.UseResponseCaching();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

In de voorgaande code:

  • Middleware die niet wordt toegevoegd bij het maken van een nieuwe web-app met afzonderlijke gebruikersaccounts wordt uitgecommentarieerd.
  • Niet elke middleware wordt in deze exacte volgorde weergegeven, maar veel wel. Bijvoorbeeld:
    • UseCors, UseAuthenticationen UseAuthorization moeten worden weergegeven in de weergegeven volgorde.
    • UseCors moet momenteel vanwege UseResponseCachingworden weergegeven voordat .
    • UseRequestLocalization moet worden weergegeven vóór middleware die de aanvraagcultuur kan controleren (bijvoorbeeld app.UseMvcWithDefaultRoute()).

In sommige scenario's heeft middleware een andere volgorde. Caching en compressievolgorde zijn bijvoorbeeld scenariospecifiek en er zijn meerdere geldige volgordes. Bijvoorbeeld:

app.UseResponseCaching();
app.UseResponseCompression();

Met de voorgaande code kan CPU-besparing worden bereikt door het gecomprimeerde antwoord in de cache op te slaan, maar het kan gebeuren dat u meerdere representaties van een resource in de cache opslaat met behulp van compressiealgoritmen zoals Gzip of Brotli.

In de volgende volgorde worden statische bestanden gecombineerd om gecomprimeerde statische bestanden in de cache toe te staan:

app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();

Met de volgende Startup.Configure methode worden middlewareonderdelen toegevoegd voor veelvoorkomende app-scenario's:

  1. Afhandeling van uitzonderingen/fouten
    • Wanneer de app wordt uitgevoerd in de ontwikkelomgeving:
      • Middleware voor uitzonderingspagina's voor ontwikkelaars (UseDeveloperExceptionPage) rapporteert runtimefouten in de app.
      • Databasefoutpagina Middleware rapporteert databaseruntimefouten.
    • Wanneer de app wordt uitgevoerd in de productieomgeving:
      • Uitzonderingshandler Middleware (UseExceptionHandler) verwerkt foutmeldingen die worden gegenereerd in de volgende middlewares.
      • Met HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) wordt de Strict-Transport-Security-header toegevoegd.
  2. HTTPS Redirection Middleware (UseHttpsRedirection) leidt HTTP-aanvragen om naar HTTPS.
  3. Static File Middleware (UseStaticFiles) levert statische bestanden en onderbreekt verdere verwerking van verzoeken.
  4. Cookie Policy Middleware (UseCookiePolicy) voldoet aan de app aan de AVG-regelgeving (General Data Protection Regulation) van de EU.
  5. Routing Middleware (UseRouting) om aanvragen te routeren.
  6. Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang hebben tot beveiligde resources.
  7. Met Authorization Middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
  8. Session Middleware (UseSession) brengt de sessiestatus tot stand en onderhoudt deze. Als de app de sessiestatus gebruikt, roept u Session Middleware aan na Cookie Policy Middleware en voor MVC Middleware.
  9. Endpoint Routing Middleware (UseEndpoints met MapRazorPages) om Razor Pages-eindpunten toe te voegen aan de verzoekverwerkingspijplijn.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseSession();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

In de voorgaande voorbeeldcode wordt elke middleware-extensiemethode weergegeven op IApplicationBuilder via de Microsoft.AspNetCore.Builder naamruimte.

UseExceptionHandler is het eerste middlewareonderdeel dat aan de pijplijn is toegevoegd. De Exception Handler Middleware vangt daarom alle uitzonderingen op die optreden in latere aanroepen.

Static File Middleware wordt vroeg in de pijplijn aangeroepen, zodat het aanvragen kan afhandelen en de resterende onderdelen kan omzeilen. De Static File Middleware biedt geen autorisatiecontroles. Alle bestanden die worden geleverd door Static File Middleware, waaronder bestanden onder wwwroot, zijn openbaar beschikbaar. Zie Statische bestanden in ASP.NET Corevoor een benadering voor het beveiligen van statische bestanden.

Als de aanvraag niet wordt verwerkt door de Static File Middleware, wordt deze doorgegeven aan de verificatie-middleware (UseAuthentication), waarmee verificatie wordt uitgevoerd. Authenticatie omzeilt geen niet-geauthenticeerde verzoeken. Hoewel verificatie-middleware aanvragen verifieert, vindt autorisatie (en afwijzing) alleen plaats nadat MVC een specifieke Razor Pagina of MVC-controller en -actie selecteert.

In het volgende voorbeeld ziet u een middlewarevolgorde waarin aanvragen voor statische bestanden worden verwerkt door Static File Middleware vóór Response Compression Middleware. Statische bestanden worden niet gecomprimeerd met deze middlewarevolgorde. De reacties van de Razor-pagina kunnen worden gecomprimeerd.

public void Configure(IApplicationBuilder app)
{
    // Static files aren't compressed by Static File Middleware.
    app.UseStaticFiles();

    app.UseRouting();

    app.UseResponseCompression();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Voor SPA's (Single Page Applications) komt de spa-middleware UseSpaStaticFiles meestal de laatste in de middleware-pijplijn. De spa middleware komt als laatste:

  • Om alle andere middlewares eerst te laten reageren op overeenkomende aanvragen.
  • Om toe te staan dat SPA's met client-side routing worden uitgevoerd voor alle routes die niet door de serverapplicatie worden herkend.

Zie de handleidingen voor de projectsjablonen React en Angular voor meer informatie over SPA's.

Doorgestuurde headers volgorde van de middleware

Forwarded Headers-middleware moet vóór andere middleware worden uitgevoerd. Deze volgorde zorgt ervoor dat de middleware die afhankelijk is van informatie over doorgestuurde headers de headerwaarden kan gebruiken voor verwerking. Zie Forwarded Headers Middlewareom het [Forwarded Headers Middleware] uit te voeren na de middleware voor diagnosticeren en fouten afhandelen.

De middleware-pijplijn vertakken

Map extensies worden gebruikt als een conventie voor het vertakken van de pijplijn. Map splitst de aanvraagpijplijn op basis van overeenkomende elementen van het opgegeven aanvraagpad. Als het aanvraagpad begint met het opgegeven pad, wordt de vertakking uitgevoerd.

public class Startup
{
    private static void HandleMapTest1(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 1");
        });
    }

    private static void HandleMapTest2(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map Test 2");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1", HandleMapTest1);

        app.Map("/map2", HandleMapTest2);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate.");
        });
    }
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de vorige code.

Verzoek Antwoord
localhost:1234 Hallo vanuit de niet-Map-gedelegeerde.
localhost:1234/map1 Kaarttest 1
localhost:1234/map2 Kaarttest 2
localhost:1234/map3 Hallo vanuit de niet-Map-gedelegeerde.

Wanneer Map wordt gebruikt, worden de overeenkomende padsegmenten verwijderd uit HttpRequest.Path en toegevoegd aan HttpRequest.PathBase voor elke aanvraag.

Map ondersteunt nesten, bijvoorbeeld:

app.Map("/level1", level1App => {
    level1App.Map("/level2a", level2AApp => {
        // "/level1/level2a" processing
    });
    level1App.Map("/level2b", level2BApp => {
        // "/level1/level2b" processing
    });
});

Map kan ook meerdere segmenten tegelijk overeenkomen:

public class Startup
{
    private static void HandleMultiSeg(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Map multiple segments.");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Map("/map1/seg1", HandleMultiSeg);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate.");
        });
    }
}

MapWhen vertakt de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. Elk predicaat van het type Func<HttpContext, bool> kan worden gebruikt om aanvragen toe te wijzen aan een nieuwe vertakking van de pijplijn. In het volgende voorbeeld wordt een predicaat gebruikt om de aanwezigheid van een queryreeksvariabele te detecteren branch:

public class Startup
{
    private static void HandleBranch(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            var branchVer = context.Request.Query["branch"];
            await context.Response.WriteAsync($"Branch used = {branchVer}");
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        app.MapWhen(context => context.Request.Query.ContainsKey("branch"),
                               HandleBranch);

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from non-Map delegate.");
        });
    }
}

In de volgende tabel ziet u de aanvragen en antwoorden van http://localhost:1234 met behulp van de vorige code:

Verzoek Antwoord
localhost:1234 Hallo vanuit de niet-Map-gedelegeerde.
localhost:1234/?branch=main Gebruikte vertakking = hoofdtak

UseWhen vertakt ook de aanvraagpijplijn op basis van het resultaat van het opgegeven predicaat. In tegenstelling tot MapWhen, wordt deze vertakking opnieuw aan de hoofdpijplijn gekoppeld als deze geen kortsluiting heeft of een terminal-middleware bevat:

public class Startup
{
    private void HandleBranchAndRejoin(IApplicationBuilder app, ILogger<Startup> logger)
    {
        app.Use(async (context, next) =>
        {
            var branchVer = context.Request.Query["branch"];
            logger.LogInformation("Branch used = {branchVer}", branchVer);

            // Do work that doesn't write to the Response.
            await next();
            // Do other work that doesn't write to the Response.
        });
    }

    public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
    {
        app.UseWhen(context => context.Request.Query.ContainsKey("branch"),
                               appBuilder => HandleBranchAndRejoin(appBuilder, logger));

        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello from main pipeline.");
        });
    }
}

In het voorgaande voorbeeld wordt een antwoord van 'Hello from main pipeline' geschreven voor alle aanvragen. Als de aanvraag een queryreeksvariabele bevat branch, wordt de waarde vastgelegd voordat de hoofdpijplijn opnieuw wordt toegevoegd.

Ingebouwde middleware

ASP.NET Core wordt geleverd met de volgende middlewareonderdelen. De kolom Order bevat notities over middlewareplaatsing in de pijplijn voor aanvraagverwerking en onder welke voorwaarden de middleware de verwerking van aanvragen kan beëindigen. Wanneer een middleware de aanvraagverwerkingspijplijn kortcircuitt en voorkomt dat verdere downstream-middleware een aanvraag verwerkt, wordt dit een terminal-middlewaregenoemd. Zie de sectie Een middleware-pijplijn maken met IApplicationBuilder voor meer informatie over kortsluiting.

Middleware Beschrijving Bevelen
verificatie Biedt ondersteuning voor verificatie. Voordat HttpContext.User nodig is. Terminal voor OAuth-callbacks.
autorisatie Biedt autorisatieondersteuning. Direct na de authenticatie-middleware.
Cookie Beleid Houdt toestemming van gebruikers bij voor het opslaan van persoonlijke gegevens en dwingt minimumstandaarden af voor cookie velden, zoals secure en SameSite. Voordat de middleware cookies uitgeeft. Voorbeelden: verificatie, sessie, MVC (TempData).
CORS Hiermee wordt Cross-Origin Resource Sharing geconfigureerd. Voordat onderdelen CORS gebruiken. UseCors moet momenteel vóór UseResponseCaching gaan vanwege fout .
Diagnostische gegevens Verschillende afzonderlijke middlewares die een uitzonderingspagina voor ontwikkelaars bieden, uitzonderingsafhandeling, statuscodepagina's en de standaardwebpagina voor nieuwe apps. Voordat onderdelen fouten genereren. Terminal voor uitzonderingen of het leveren van de standaardwebpagina voor nieuwe apps.
Doorgestuurde Headers De via een proxy aangeleverde kopteksten worden doorgestuurd naar het huidige verzoek. Voordat componenten de bijgewerkte velden gebruiken. Voorbeelden: schema, host, client-IP, methode.
gezondheidscontrole Controleert de status van een ASP.NET Core-app en de bijbehorende afhankelijkheden, zoals het controleren van de beschikbaarheid van de database. Terminal als een aanvraag overeenkomt met een statuscontrole-eindpunt.
Doorgifte van Kopteksten Hiermee worden HTTP-headers van de binnenkomende aanvraag doorgegeven aan de uitgaande HTTP-clientaanvragen.
HTTP-methode overschrijven Hiermee kan een binnenkomende POST-aanvraag de methode overschrijven. Voordat onderdelen gebruikmaken van de bijgewerkte methode.
HTTPS-omleiding Alle HTTP-aanvragen omleiden naar HTTPS. Voordat onderdelen de URL gebruiken.
HTTP Strict Transport Security (HSTS) Middleware voor beveiligingsverbeteringen waarmee een speciale antwoordheader wordt toegevoegd. Voordat de antwoorden worden verzonden, en nadat de onderdelen de aanvragen hebben gewijzigd. Voorbeelden: Doorgestuurde headers, URL-herschrijven.
MVC Verwerkt aanvragen met MVC/Razor Pages. Terminal als een aanvraag overeenkomt met een route.
OWIN Interoperabiliteit met op OWIN gebaseerde apps, servers en middleware. Terminal als de OWIN Middleware de aanvraag volledig verwerkt.
Responsecaching Biedt ondersteuning voor het opslaan van antwoorden in cache. Voordat je onderdelen gebruikt die caching vereisen. UseCORS moet vóór UseResponseCachingkomen.
Antwoordcompressie Biedt ondersteuning voor het comprimeren van antwoorden. Voordat onderdelen moeten worden gecomprimeerd.
Verzoek om lokalisatie Biedt lokalisatieondersteuning. Voordat gevoelige onderdelen worden gelokaliseerd. Moet verschijnen na Routing Middleware bij gebruik van RouteDataRequestCultureProvider.
eindpuntroutering Hiermee definieert en beperkt u aanvraagroutes. Terminal voor overeenkomende routes.
SPA Verwerkt alle aanvragen vanaf dit punt in de middlewareketen door de standaardpagina voor de toepassing met één pagina (SPA) te retourneren Laat in de keten, zodat andere middleware voor het serveren van statische bestanden, MVC-acties, enz., voorrang krijgt.
sessie Biedt ondersteuning voor het beheren van gebruikerssessies. Voordat onderdelen een sessie vereisen.
statische bestanden Biedt ondersteuning voor het leveren van statische bestanden en bladeren door mappen. Terminal als een aanvraag overeenkomt met een bestand.
URL herschrijven Biedt ondersteuning voor het herschrijven van URL's en het omleiden van aanvragen. Voordat onderdelen de URL gebruiken.
WebSockets Hiermee schakelt u het WebSocket-protocol in. Voordat noodzakelijke onderdelen WebSocket-verzoeken kunnen accepteren.

Aanvullende informatiebronnen