Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Notitie
Dit is niet de nieuwste versie van dit artikel. Zie de .NET 10-versie van dit artikel voor 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 10-versie van dit artikel voor de huidige release.
Middleware is software dat wordt geïntegreerd in een applicatiepijplijn om verzoeken en antwoorden af te handelen. Elke middleware:
- Hiermee kiest u of de aanvraag moet worden doorgegeven aan de volgende middleware in de pijplijn.
- Kan werk uitvoeren voor en na de volgende middleware in de pijplijn.
Aanvraagdelegen worden gebruikt om de aanvraagpijplijn te bouwen. De aanvraagdelegen verwerken elke HTTP-aanvraag.
Configureer requestdelegates met behulp van de uitbreidingsmethoden Run, Map en Use. U kunt een afzonderlijke aanvraagdelegatie inline opgeven als een anonieme methode (inline-middleware genoemd) of deze definiëren in een herbruikbare klasse. Deze inline anonieme methoden of herbruikbare klassen worden middleware- of middlewareonderdelen genoemd. Elke middleware in de aanvraagpijplijn is verantwoordelijk voor het aanroepen van de volgende middleware 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.
Zie HTTP-modules migreren naar ASP.NET Core middleware voor meer informatie over het verschil tussen aanvraagpijplijnen in ASP.NET Core en ASP.NET 4.x met aanvullende middlewarevoorbeelden.
Rol van middleware per app-type
Browseraanvragen aan de serverzijde Blazor, Razor pagina's en MVC-procesbrowseraanvragen 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
Zie Diagnostische Code Analysis in ASP.NET Core Apps voor meer informatie over de compilerplatformanalyses van ASP.NET Core die app-code voor kwaliteit inspecteren.
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.
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.
Notitie
Als u lokaal wilt experimenteren met de codevoorbeelden in deze sectie, maakt u een ASP.NET Core-app met behulp van de projectsjabloon ASP.NET Core Empty . Als u de .NET CLI gebruikt, is web de korte naam van de sjabloon (dotnet new web).
De eenvoudigste ASP.NET Core-app roept Run aan om een enkele terminal-middleware in te stellen als een anonieme functiegemachtigde om aanvragen te verwerken zonder een aanvraagpijplijn.
In het volgende voorbeeld:
- De aanroep naar RunExtensions.Run wordt bij elke aanvraag aangeroepen en schrijft 'Hello world!' naar het antwoord.
- De aanroep van WebApplication.Run aan het einde van het codeblok voert de app uit en blokkeert de aanroepende thread totdat de host wordt afgesloten.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
app.Run();
Antwoord bij het openen van de app in een browser bij de start-URL:
Hello world!
Koppel meerdere verzoekafgevaardigden aan elkaar met Use. De parameter next vertegenwoordigt de volgende gemachtigde in de pijplijn. Doorgaans kunt u acties uitvoeren vóór en na de next gemachtigde.
In het volgende voorbeeld ziet u:
- Twee Use oproepen, die elk naar de console schrijven:
- Waar werk kan worden uitgevoerd dat naar het antwoord kan schrijven (
context.Response, HttpResponse). - Waar werk kan worden uitgevoerd dat niet naar de respons schrijft nadat de
next-parameter is aangeroepen.
- Waar werk kan worden uitgevoerd dat naar het antwoord kan schrijven (
- Een terminal aanvraag delegate met een aanroep naar RunExtensions.Run die "Hello world!" naar de response schrijft.
- Een laatste Use aanroep, die nooit wordt uitgevoerd omdat deze de gedelegeerde van de Run terminalaanvraag volgt.
- Een aanroep van WebApplication.Run aan het einde van het codeblok om de app te draaien en de aanroepende thread te blokkeren totdat de host afsluit.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Use(async (context, next) =>
{
Console.WriteLine("Work that can write to the response. (1)");
await next.Invoke(context);
Console.WriteLine("Work that doesn't write to the response. (1)");
});
app.Use(async (context, next) =>
{
Console.WriteLine("Work that can write to the response. (2)");
await next.Invoke(context);
Console.WriteLine("Work that doesn't write to the response. (2)");
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
app.Use(async (context, next) =>
{
Console.WriteLine("This statement isn't reached. (3)");
await next.Invoke(context);
Console.WriteLine("This statement isn't reached. (3)");
});
app.Run();
In het consolevenster van de app wanneer de app wordt uitgevoerd:
Werk dat naar het antwoord kan schrijven. (1)
Werk dat naar het antwoord kan schrijven. (2)
Werk dat niet naar de reactie schrijft. (2)
Werk dat niet naar de reactie schrijft. (1)
Kortsluiting van de aanvraagpijplijn is vaak wenselijk omdat dit onnodig werk voorkomt.
Middleware voor statische bestanden kan bijvoorbeeld fungeren als eindmiddleware door een verzoek om een statisch bestand te verwerken en de rest van de pijplijn kort te sluiten. Middleware die aan de pijplijn is toegevoegd voordat de terminal-middleware, blijft nog steeds code verwerken na hun next.Invoke instructies. Als u niet van plan bent om next.Invoke aan te roepen omdat u de pijplijn wilt beëindigen, gebruik een Run delegate in plaats van de Use extensiemethode aan te roepen.
Bel niet next.Invoke tijdens of nadat het antwoord naar de client is verzonden. Nadat een HttpResponse is gestart, resulteren wijzigingen in een uitzondering. Als u bijvoorbeeld headers of een antwoordstatuscode instelt, wordt er een uitzondering gegenereerd nadat het antwoord is gestart. Schrijven naar de hoofdtekst van het antwoord na het aanroepen next kan:
- Veroorzaakt een schending van een protocol, zoals het schrijven van meer bytes naar het antwoord dan de inhoudslengte van het opgegeven antwoord (
Content-Lengthheaderwaarde). - Beschadig de bestandsindeling, zoals het schrijven van een HTML-voettekst naar een CSS-bestand.
Als u wilt bepalen of het antwoord is gestart, controleert u de waarde van HasStarted.
Zie Short-circuit middleware na routeringvoor meer informatie.
Run gemachtigde
Een Run gedelegeerde ontvangt geen next parameter. De eerste Run gemachtigde beëindigt altijd de pijplijn.
Run is ook een conventie en sommige middleware kan methoden beschikbaar maken Run die aan het einde van de pijplijn worden uitgevoerd.
Eventuele Use- of Run-gedelegeerden na de eerste Run-gedelegeerde worden niet aangeroepen.
De middleware-pijplijn vertakken
Map-extensies worden gebruikt als conventie om de verwerkingspijplijn van aanvragen te vertakken. 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.
In het volgende voorbeeld wordt HandleMap1 aangeroepen voor aanvragen aan /map1, en HandleMap2 wordt aangeroepen voor aanvragen aan /map2.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Map("/map1", HandleMap1);
app.Map("/map2", HandleMap2);
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from the non-Map delegate!");
});
app.Run();
private static void HandleMap1(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map 1");
});
}
private static void HandleMap2(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map 2");
});
}
In de volgende tabel ziet u de aanvragen en antwoorden met behulp van de voorgaande code.
| Verzoek | Antwoord |
|---|---|
/ |
Hello from the non-Map delegate. |
/map1 |
Map 1 |
/map2 |
Map 2 |
/map3 |
Hello from the non-Map delegate. |
Wanneer Map wordt gebruikt, worden de overeenkomende padsegmenten verwijderd uit HttpRequest.Path en toegevoegd aan HttpRequest.PathBase voor elke aanvraag.
Map kan in één keer overeenkomen met meerdere segmenten:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Map("/map1/segment1", HandleMultipleSegments);
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from the non-Map delegate.");
});
app.Run();
private static void HandleMultipleSegments(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Processing '/map1/segment1'");
});
}
In de volgende tabel ziet u de aanvragen en antwoorden met behulp van de voorgaande code.
| Verzoek | Antwoord |
|---|---|
/ |
Hello from the non-Map delegate. |
/map1/segment1 |
Processing '/map1/segment1' |
Map biedt ondersteuning voor nesten:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Map("/level1", level1App => {
level1App.Map("/level2a", level2AApp => {
level2AApp.Run(async context =>
{
await context.Response.WriteAsync("Processing '/level1/level2a'");
});
});
level1App.Map("/level2b", level2BApp => {
level2BApp.Run(async context =>
{
await context.Response.WriteAsync("Processing '/level1/level2b'");
});
});
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from the non-Map delegate!");
});
app.Run();
In de volgende tabel ziet u de aanvragen en antwoorden met behulp van de voorgaande code.
| Verzoek | Antwoord |
|---|---|
/ |
Hello from the non-Map delegate. |
/level1/level2a |
Processing '/level1/level2a' |
/level1/level2b |
Processing '/level1/level2b' |
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 met de naam 'branch'' te detecteren:
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 the non-Map delegate.");
});
app.Run();
private 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 met behulp van de voorgaande code.
| Verzoek | Antwoord |
|---|---|
/ |
Hello from the non-Map delegate. |
/?branch=main |
Branch used = 'main' |
UseWhen kan de aanvraagpijplijn vertakken op basis van het resultaat van het opgegeven predicaat. In tegenstelling tot MapWhen, wordt de vertakking opnieuw aan de hoofdpijplijn gekoppeld 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 the 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.ToString());
Console.WriteLine("Work that can write to the response.");
await next.Invoke(context);
Console.WriteLine("Work that doesn't write to the response.");
});
}
In het voorgaande voorbeeld wordt een antwoord van 'Hello from the non-Map delegate.' geschreven voor alle aanvragen. Als de aanvraag een queryreeksvariabele met de naam 'branch' bevat, wordt de waarde vastgelegd voordat de hoofdpijplijn opnieuw wordt toegevoegd.
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.
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:
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.
});
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.
Middleware voor statische bestanden kan bijvoorbeeld fungeren als eindmiddleware door een verzoek om 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 het proberen te 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 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 nuttige aanwijzing om aan te geven of er headers zijn verzonden of naar de inhoud is geschreven.
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:
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd delegate.");
});
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.
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. U kunt elk predicaat van het type Func<HttpContext, bool> gebruiken om aanvragen toe te wijzen aan een nieuwe vertakking van de pijplijn. In het volgende voorbeeld detecteert een predicaat de aanwezigheid van een queryreeksvariabele 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 niet onderbroken wordt of geen 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.ToString());
// 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.
Middleware automatisch toegevoegd door WebApplication
WebApplicationvoegt automatisch de volgende middleware toe aan ASP.NET Core apps, afhankelijk van bepaalde voorwaarden:
-
UseDeveloperExceptionPagewordt eerst toegevoegd wanneer hetHostingEnvironmentis"Development". -
UseRoutingwordt als tweede toegevoegd als de gebruikerscodeUseRoutingnog niet heeft aangeroepen en als er eindpunten, bijvoorbeeld zoalsapp.MapGet, zijn geconfigureerd. -
UseEndpointswordt toegevoegd aan het einde van de middleware-pijplijn als er eindpunten zijn geconfigureerd. -
UseAuthenticationwordt onmiddellijk toegevoegd naUseRoutingals de gebruikerscode nog nietUseAuthenticationheeft aangeroepen en alsIAuthenticationSchemeProvidergedetecteerd kan worden in de serviceprovider.IAuthenticationSchemeProviderwordt standaard toegevoegd wanneer uAddAuthenticationgebruikt, en services worden gedetecteerd met behulp vanIServiceProviderIsService. -
UseAuthorizationwordt vervolgens toegevoegd indien de gebruikerscode niet al heeft aangeroepenUseAuthorizationenIAuthorizationHandlerProviderkan worden gedetecteerd in de serviceprovider.IAuthorizationHandlerProviderwordt standaard toegevoegd wanneer uAddAuthorizationgebruikt, en services worden gedetecteerd met behulp vanIServiceProviderIsService. - Door de gebruiker geconfigureerde middleware en eindpunten worden toegevoegd tussen
UseRoutingenUseEndpoints.
De volgende code is effectief wat de automatische middleware die aan de app wordt toegevoegd, produceert:
if (isDevelopment)
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
if (isAuthenticationConfigured)
{
app.UseAuthentication();
}
if (isAuthorizationConfigured)
{
app.UseAuthorization();
}
// user middleware/endpoints
app.CustomMiddleware(...);
app.MapGet("/", () => "hello world");
// end user middleware/endpoints
app.UseEndpoints(e => {});
In sommige gevallen is de standaard-middlewareconfiguratie niet juist voor de app en moet deze worden gewijzigd. Moet bijvoorbeeld UseCors worden aangeroepen voor UseAuthentication en UseAuthorization. De app moet UseAuthentication en UseAuthorization aanroepen als UseCors wordt aangeroepen.
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
Als middleware moet worden uitgevoerd voordat routekoppeling plaatsvindt, moet UseRouting worden aangeroepen en moet de middleware worden geplaatst voordat de aanroep naar UseRouting plaatsvindt.
UseEndpoints is in dit geval niet vereist, omdat deze automatisch wordt toegevoegd zoals eerder beschreven:
app.Use((context, next) =>
{
return next(context);
});
app.UseRouting();
// other middleware and endpoints
Wanneer u een terminal-middleware toevoegt:
- De middleware moet worden toegevoegd na
UseEndpoints. - De app moet
UseRoutingenUseEndpointsaanroepen zodat de terminal-middleware op de juiste locatie kan worden geplaatst.
app.UseRouting();
app.MapGet("/", () => "hello world");
app.UseEndpoints(e => {});
app.Run(context =>
{
context.Response.StatusCode = 404;
return Task.CompletedTask;
});
Terminal-middleware is middleware die werkt wanneer er geen eindpunt is dat de aanvraag verwerkt.
WebApplication voegt automatisch de volgende middleware toe in ASP.NET Core-apps, afhankelijk van bepaalde voorwaarden:
UseDeveloperExceptionPage wordt eerst toegevoegd wanneer hostingenvironment is
"Development".UseRouting wordt als tweede toegevoegd als de gebruikerscode nog niet
UseRoutingheeft aangeroepen en als eindpunten zijn geconfigureerd, bijvoorbeeldapp.MapGet.UseEndpoints wordt toegevoegd aan het einde van de middleware-pijplijn als eindpunten zijn geconfigureerd.
UseAuthentication wordt direct na
UseRoutingtoegevoegd, als de gebruikerscodeUseAuthenticationnog niet heeft aangeroepen en als IAuthenticationSchemeProvider kan worden gedetecteerd in de service-provider.IAuthenticationSchemeProviderwordt standaard toegevoegd wanneer u AddAuthentication gebruikt en services worden gedetecteerd met behulp van IServiceProviderIsService.UseAuthorization wordt vervolgens toegevoegd als de gebruikerscode nog niet
UseAuthorizationheeft aangeroepen en als IAuthorizationHandlerProvider kan worden gedetecteerd in de service-provider.IAuthorizationHandlerProviderwordt standaard toegevoegd wanneer u AddAuthorization gebruikt en services worden gedetecteerd met behulp vanIServiceProviderIsService.Door de gebruiker geconfigureerde middleware en eindpunten worden toegevoegd tussen
UseRoutingenUseEndpoints.
De volgende code is effectief wat de automatische middleware die aan de app wordt toegevoegd, produceert:
if (isDevelopment)
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
if (isAuthenticationConfigured)
{
app.UseAuthentication();
}
if (isAuthorizationConfigured)
{
app.UseAuthorization();
}
// User middleware/endpoints
app.CustomMiddleware(...);
app.MapGet("/", () => "hello world");
// End user middleware/endpoints
app.UseEndpoints(e => {});
In sommige gevallen is de standaard-middlewareconfiguratie niet juist voor de app en moet deze worden gewijzigd. Moet bijvoorbeeld UseCors worden aangeroepen voor UseAuthentication en UseAuthorization. De app moet UseAuthentication en UseAuthorization aanroepen als UseCors wordt aangeroepen.
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
Als middleware moet worden uitgevoerd voordat routekoppeling plaatsvindt, moet UseRouting worden aangeroepen en moet de middleware vóór de aanroep naar UseRouting worden geplaatst.
UseEndpoints is in dit geval niet vereist omdat deze automatisch wordt toegevoegd zoals eerder beschreven:
app.Use((context, next) =>
{
return next(context);
});
app.UseRouting();
// Other middleware and endpoints
Wanneer u een terminal-middleware toevoegt:
De middleware moet worden toegevoegd na
UseEndpoints.De app moet
UseRoutingenUseEndpointsaanroepen zodat de terminal-middleware op de juiste locatie kan worden geplaatst.
app.UseRouting();
app.MapGet("/", () => "hello world");
app.UseEndpoints(e => {});
app.Run(context =>
{
context.Response.StatusCode = 404;
return Task.CompletedTask;
});
Terminal-middleware is middleware die werkt wanneer er geen eindpunt is dat de aanvraag verwerkt.
Zie Prevent Cross-Site Request Forgery-aanvallen (XSRF/CSRF) in ASP.NET Core voor informatie over antiforgery-middleware in minimale API's.
Middleware-volgorde
De volgorde waarin middleware wordt weergegeven in het Program-bestand van de app, bepaalt de volgorde waarin middleware worden aangeroepen bij een verzoek, met de omgekeerde volgorde voor de respons.
U hebt volledige controle over de volgorde van middleware en de mogelijkheid om aangepaste middleware toe te voegen voor aanvraagverwerkingsscenario's. Houd er rekening mee dat de volgorde van middleware essentieel kan zijn voor beveiliging, prestaties en functionaliteit.
In de volgende voorbeelden ziet u de middlewarevolgorde voor veelvoorkomende app-scenario's. Elke middleware-extensiemethode wordt via de WebApplicationBuilder naamruimte op Microsoft.AspNetCore.Builder aangeboden:
- Uitzonderings- en foutafhandeling
- Wanneer de app wordt uitgevoerd in de
Developmentomgeving:- Middleware voor de ontwikkelaarsexceptiepagina (UseDeveloperExceptionPage) rapporteert runtimefouten in de app.
- Middleware voor databasefoutpagina’s (UseDatabaseErrorPage) meldt runtimefouten in de database.
- Wanneer de app wordt uitgevoerd in de
Productionomgeving:- Middleware voor uitzonderingsafhandeling (UseExceptionHandler) onderschept uitzonderingen die in de volgende middleware worden gegenereerd.
- Http Strict Transport Security (HSTS) protocol middleware (UseHsts) voegt de
Strict-Transport-Securityheader toe.
- Wanneer de app wordt uitgevoerd in de
- MET HTTPS-omleidings-middleware (UseHttpsRedirection) worden HTTP-aanvragen omgeleid naar HTTPS.
- Middleware voor statische bestanden (indien nodig, UseStaticFiles) serveert statische bestanden en stopt verdere verwerking van de aanvraag.
- Cookie policy middleware (UseCookiePolicy) brengt de app in overeenstemming met de Algemene verordening gegevensbescherming (AVG).
- Routeringsmiddleware (UseRouting) om verzoeken te routeren.
- Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang krijgen tot beveiligde resources.
- Met autorisatie-middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
- Antiforgery middleware (UseAntiforgery) voegt antiforgery-middleware toe aan de pijplijn. UseAntiforgery moet worden geplaatst na aanroepen van UseAuthentication en UseAuthorization.
- Sessie-middleware (Razor alleen voor Pages en MVC, UseSession) stelt de sessiestatus vast en onderhoudt deze. Als de app sessiestatus gebruikt, roept u sessie-middleware aan na cookie beleids-middleware en vóór Razor Pages/MVC middleware.
- Middleware voor eindpuntroutering
- MapRazorComponents om onderdeeleindpunten Razor toe te voegen aan de request pipeline.
- MapRazorPages om pagina-eindpunten toe te voegen Razor aan de aanvraagpijplijn.
- MapControllerRoute om controllereindpunten toe te voegen aan de aanvraagpijplijn.
Typische Blazor Web App middleware-pijplijn:
app.UseWebAssemblyDebugging(); // Development environment with client-side rendering
app.UseMigrationsEndPoint(); // Development environment with ASP.NET Core Identity
app.UseExceptionHandler("/Error", createScopeForErrors: true); // Non-Development environment
app.UseHsts(); // Non-Development environment with HTTPS protocol
app.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
app.UseHttpsRedirection(); // With HTTPS protocol
app.UseAntiforgery();
app.MapStaticAssets();
app.MapRazorComponents<App>(); // With additional extension methods for render modes
app.MapAdditionalIdentityEndpoints(); // With ASP.NET Core Identity
app.Run();
Typische Razor Pages/MVC-middleware pipeline:
app.UseMigrationsEndPoint(); // Development environment with ASP.NET Core Identity
app.UseExceptionHandler("/Error"); // Non-Development environment
app.UseHsts(); // Non-Development environment with HTTPS protocol
app.UseHttpsRedirection(); // With HTTPS protocol
// app.UseCookiePolicy();
app.UseRouting(); // If not called, runs at the beginning of the pipeline by default
// app.UseRateLimiter();
// app.UseRequestLocalization();
// app.UseCors();
// app.UseAuthentication(); // Called internally for ASP.NET Core Identity
app.UseAuthorization();
// app.UseSession();
// app.UseResponseCompression();
// app.UseResponseCaching();
app.MapStaticAssets();
app.MapControllerRoute(...); // For MVC controllers
app.MapRazorPages(); // For Razor Pages pages
app.MapControllers(); // With authentication in a Razor Pages app
app.Run();
In de voorgaande code:
- CORS-middleware (UseCors), verificatie-middleware (UseAuthentication) en autorisatie-middleware (UseAuthorization) moeten worden weergegeven in de weergegeven volgorde.
- CORS-middleware (UseCors) moet vóór middleware voor antwoordcache (UseResponseCaching) komen om CORS-headers toe te voegen aan elk verzoek, inclusief in de cache opgeslagen antwoorden. Zie Het is niet duidelijk dat UseCORS vóór UseResponseCaching (
dotnet/aspnetcore#23218) moet komen voor meer informatie. - Middleware voor aanvraaglokalisatie (UseRequestLocalization) moet vóór middleware komen die mogelijk de cultuur van de aanvraag controleert, bijvoorbeeld middleware voor statische bestanden (UseStaticFiles).
- Middleware voor snelheidsbeperking (UseRateLimiter) moet worden aangeroepen na routeringsmiddleware (UseRouting) wanneer eindpuntspecifieke API's voor snelheidsbeperking worden gebruikt. Als het
[EnableRateLimiting]kenmerk bijvoorbeeld wordt gebruikt, moet de snelheidsbeperkings-middleware worden aangeroepen na het routeren van middleware. Wanneer u alleen globale limieten aanroept, kunnen middleware voor snelheidsbeperking worden aangeroepen voordat middleware voor routering wordt aangeroepen.
In sommige scenario's heeft middleware een andere volgorde. De volgorde van caching en compressie is bijvoorbeeld afhankelijk van de specificatie van de app. In de volgende volgorde kan het CPU-gebruik worden verminderd door het gecomprimeerde antwoord in de cache te plaatsen, maar de app kan uiteindelijk meerdere weergaven van een resource opslaan met behulp van verschillende compressiealgoritmen, zoals Gzip of Brotli:
app.UseResponseCaching();
app.UseResponseCompression();
Statische assets worden doorgaans vroeg in de pijplijn geleverd, zodat de app de aanvraagverwerking kan omzeilen om de prestaties te verbeteren.
Authenticatie omzeilt geen niet-geauthenticeerde verzoeken. Hoewel verificatie-middleware aanvragen verifieert, vindt autorisatie plaats nadat het framework een Razor onderdeel in een Blazor Web App, een pagina in een Razor Pagina-app of een controller en actie in een MVC-app selecteert.
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.
De Endpoint middleware in het voorgaande diagram voert de filterpijplijn uit voor het bijbehorende app-type: MVC of Razor Pages.
In het voorgaande diagram wordt de middleware Routing weergegeven na Statische bestanden. Deze volgorde is de manier waarop de projectsjablonen werken, doordat app.UseRouting expliciet wordt aangeroepen. Als u app.UseRoutingniet aanroept, wordt de Routing middleware standaard uitgevoerd aan het begin van de pijplijn. Zie Routingvoor meer informatie.
De volgorde waarin u middlewareonderdelen in het Program.cs bestand toevoegt, 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.
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:
- Uitgecommentarieerde middleware wordt niet toegevoegd wanneer u een nieuwe web-app maakt met afzonderlijke gebruikersaccounts.
- Niet elke middleware wordt in deze exacte volgorde weergegeven, maar veel wel. Bijvoorbeeld:
-
UseCors,UseAuthenticationenUseAuthorizationmoeten worden weergegeven in de weergegeven volgorde. -
UseCorsmoet momenteel eerst komen voordatUseResponseCaching. Deze vereiste wordt uitgelegd in probleem dotnet/aspnetcore #23218van GitHub. -
UseRequestLocalizationmoet vóór middleware staan die de aanvraagcultuur kan controleren, bijvoorbeeldapp.UseStaticFiles(). -
UseRateLimiter moet worden aangeroepen na
UseRoutingwanneer eindpuntspecifieke API's voor frequentiebeperking worden gebruikt. Als het kenmerk[EnableRateLimiting]bijvoorbeeld wordt gebruikt, moetUseRateLimiterworden aangeroepen naUseRouting. Wanneer u alleen globale begrenzers aanroept, kanUseRateLimiterworden aangeroepen voordatUseRouting.
-
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 kunt u het CPU-gebruik verminderen 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:
- Uitzonderings- en foutafhandeling
- Wanneer de app wordt uitgevoerd in de
Developmentomgeving:- Middleware voor de ontwikkelaarsexceptiepagina (UseDeveloperExceptionPage) rapporteert runtimefouten in de app.
- Middleware voor databasefoutpagina’s (UseDatabaseErrorPage) meldt runtimefouten in de database.
- Wanneer de app wordt uitgevoerd in de
Productionomgeving:- Middleware voor uitzonderingsafhandeling (UseExceptionHandler) onderschept uitzonderingen die in de volgende middleware worden gegenereerd.
- Http Strict Transport Security (HSTS) protocol middleware (UseHsts) voegt de
Strict-Transport-Securityheader toe.
- Wanneer de app wordt uitgevoerd in de
- MET HTTPS-omleidings-middleware (UseHttpsRedirection) worden HTTP-aanvragen omgeleid naar HTTPS.
- Middleware voor statische bestanden (UseStaticFiles) geeft statische bestanden terug en voorkomt verdere aanvraagverwerking.
- Cookie beleidsmiddleware (UseCookiePolicy) brengt de app in overeenstemming met de AVG-regelgeving van de EU.
- Routeringsmiddleware (UseRouting) om verzoeken te routeren.
- Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang krijgen tot beveiligde resources.
- Met autorisatie-middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
- Sessie-middleware (UseSession) brengt de sessiestatus tot stand en onderhoudt deze. Als de app de sessiestatus gebruikt, roept u sessie-middleware aan na cookie beleids-middleware en vóór MVC-middleware.
- Middleware voor eindpuntroutering (UseEndpoints met MapRazorPages) om Razor Pages-eindpunten toe te voegen aan de aanvraagverwerkingspipeline.
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 middleware voor uitzonderingsafhandeling eventuele uitzonderingen op die optreden in latere aanroepen.
Middleware voor statische bestanden wordt vroeg in de pijplijn aangeroepen, zodat deze verzoeken kan afhandelen en de verwerking kan afbreken zonder door de overige componenten te gaan. De statische bestands-middleware biedt geen autorisatiecontroles. Alle bestanden die worden geleverd door statische bestands-middleware, inclusief bestanden onder wwwroot, zijn openbaar beschikbaar. Zie Statische bestanden serveren in ASP.NET Core Apps voor een benadering voor het beveiligen van statische bestanden.
Als de aanvraag niet wordt verwerkt door de statische bestands-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 heeft geselecteerd.
In het volgende voorbeeld ziet u een middlewarevolgorde waarin aanvragen voor statische bestanden worden verwerkt door statische bestands-middleware voordat middleware voor reactiecompressie wordt verwerkt. 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();
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.
De Endpoint middleware in het voorgaande diagram voert de filterpijplijn uit voor het bijbehorende app-type: MVC of Razor Pages.
In het voorgaande diagram wordt de middleware Routing weergegeven na Statische bestanden. Deze volgorde is de manier waarop de projectsjablonen werken, doordat app.UseRouting expliciet wordt aangeroepen. Als u app.UseRoutingniet aanroept, wordt de Routing middleware standaard uitgevoerd aan het begin van de pijplijn. Zie Routingvoor meer informatie.
De volgorde waarin u middlewareonderdelen in het Program.cs bestand toevoegt, 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.
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:
- Uitgecommentarieerde middleware wordt niet toegevoegd wanneer u een nieuwe web-app maakt met afzonderlijke gebruikersaccounts.
- Niet elke middleware wordt in deze exacte volgorde weergegeven, maar veel wel. Bijvoorbeeld:
-
UseCors,UseAuthenticationenUseAuthorizationmoeten worden weergegeven in de weergegeven volgorde. -
UseCorsmoet momenteel eerst komen voordatUseResponseCaching. Deze vereiste wordt uitgelegd in probleem dotnet/aspnetcore #23218van GitHub. -
UseRequestLocalizationmoet worden weergegeven vóór middleware die de aanvraagcultuur kan controleren (bijvoorbeeldapp.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 kunt u het CPU-gebruik verminderen 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:
- Uitzonderings- en foutafhandeling
- Wanneer de app wordt uitgevoerd in de
Developmentomgeving:- Middleware voor de ontwikkelaarsexceptiepagina (UseDeveloperExceptionPage) rapporteert runtimefouten in de app.
- Middleware voor databasefoutpagina’s (UseDatabaseErrorPage) meldt runtimefouten in de database.
- Wanneer de app wordt uitgevoerd in de
Productionomgeving:- Middleware voor uitzonderingsafhandeling (UseExceptionHandler) onderschept uitzonderingen die in de volgende middleware worden gegenereerd.
- Http Strict Transport Security (HSTS) protocol middleware (UseHsts) voegt de
Strict-Transport-Securityheader toe.
- Wanneer de app wordt uitgevoerd in de
- MET HTTPS-omleidings-middleware (UseHttpsRedirection) worden HTTP-aanvragen omgeleid naar HTTPS.
- Middleware voor statische bestanden (UseStaticFiles) geeft statische bestanden terug en voorkomt verdere aanvraagverwerking.
- Cookie beleidsmiddleware (UseCookiePolicy) brengt de app in overeenstemming met de AVG-regelgeving van de EU.
- Routeringsmiddleware (UseRouting) om verzoeken te routeren.
- Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang krijgen tot beveiligde resources.
- Met autorisatie-middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
- Sessie-middleware (UseSession) brengt de sessiestatus tot stand en onderhoudt deze. Als de app de sessiestatus gebruikt, roept u sessie-middleware aan na cookie beleids-middleware en vóór MVC-middleware.
- Middleware voor eindpuntroutering (UseEndpoints met MapRazorPages) om Razor Pages-eindpunten toe te voegen aan de aanvraagverwerkingspipeline.
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 middleware voor uitzonderingsafhandeling eventuele uitzonderingen op die optreden in latere aanroepen.
Middleware voor statische bestanden wordt vroeg in de pijplijn aangeroepen, zodat deze verzoeken kan afhandelen en de verwerking kan afbreken zonder door de overige componenten te gaan. De statische bestands-middleware biedt geen autorisatiecontroles. Alle bestanden die worden geleverd door statische bestands-middleware, inclusief bestanden onder wwwroot, zijn openbaar beschikbaar. Zie Statische bestanden serveren in ASP.NET Core Apps voor een benadering voor het beveiligen van statische bestanden.
Als de aanvraag niet wordt verwerkt door de statische bestands-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 heeft geselecteerd.
In het volgende voorbeeld ziet u een middlewarevolgorde waarin aanvragen voor statische bestanden worden verwerkt door statische bestands-middleware voordat middleware voor reactiecompressie wordt verwerkt. 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();
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.
De Endpoint middleware in het voorgaande diagram voert de filterpijplijn uit voor het bijbehorende app-type: MVC of Razor Pages.
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:
- Uitgecommentarieerde middleware wordt niet toegevoegd wanneer u een nieuwe web-app maakt met afzonderlijke gebruikersaccounts.
- Niet elke middleware wordt in deze exacte volgorde weergegeven, maar veel wel. Bijvoorbeeld:
-
UseCors,UseAuthenticationenUseAuthorizationmoeten worden weergegeven in de weergegeven volgorde. -
UseCorsmoet momenteel vanwegeUseResponseCachingworden weergegeven voordat . -
UseRequestLocalizationmoet worden weergegeven vóór middleware die de aanvraagcultuur kan controleren (bijvoorbeeldapp.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:
- Uitzonderings- en foutafhandeling
- Wanneer de app wordt uitgevoerd in de
Developmentomgeving:- Middleware voor de ontwikkelaarsexceptiepagina (UseDeveloperExceptionPage) rapporteert runtimefouten in de app.
- Middleware voor databasefoutpagina's meldt runtimefouten in de database.
- Wanneer de app wordt uitgevoerd in de
Productionomgeving:- Middleware voor uitzonderingsafhandeling (UseExceptionHandler) onderschept uitzonderingen die in de volgende middleware worden gegenereerd.
- Http Strict Transport Security (HSTS) protocol middleware (UseHsts) voegt de
Strict-Transport-Securityheader toe.
- Wanneer de app wordt uitgevoerd in de
- MET HTTPS-omleidings-middleware (UseHttpsRedirection) worden HTTP-aanvragen omgeleid naar HTTPS.
- Middleware voor statische bestanden (UseStaticFiles) geeft statische bestanden terug en voorkomt verdere aanvraagverwerking.
- Cookie beleidsmiddleware (UseCookiePolicy) brengt de app in overeenstemming met de AVG-regelgeving van de EU.
- Routeringsmiddleware (UseRouting) om verzoeken te routeren.
- Verificatie-middleware (UseAuthentication) probeert de gebruiker te verifiëren voordat ze toegang krijgen tot beveiligde resources.
- Met autorisatie-middleware (UseAuthorization) kan een gebruiker toegang krijgen tot beveiligde resources.
- Sessie-middleware (UseSession) brengt de sessiestatus tot stand en onderhoudt deze. Als de app de sessiestatus gebruikt, roept u sessie-middleware aan na cookie beleids-middleware en vóór MVC-middleware.
- Middleware voor eindpuntroutering (UseEndpoints met MapRazorPages) om Razor Pages-eindpunten toe te voegen aan de aanvraagverwerkingspipeline.
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. Daarom vangt de middleware voor uitzonderingsafhandeling eventuele uitzonderingen op die optreden in latere aanroepen.
Middleware voor statische bestanden wordt vroeg in de pijplijn aangeroepen, zodat deze verzoeken kan afhandelen en de verwerking kan afbreken zonder door de overige componenten te gaan. De statische bestands-middleware biedt geen autorisatiecontroles. Alle bestanden die worden geleverd door statische bestands-middleware, inclusief bestanden onder wwwroot, zijn openbaar beschikbaar. Zie Statische bestanden serveren in ASP.NET Core Apps voor een benadering voor het beveiligen van statische bestanden.
Als de aanvraag niet wordt verwerkt door de statische bestands-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 heeft geselecteerd.
In het volgende voorbeeld ziet u een middlewarevolgorde waarin aanvragen voor statische bestanden worden verwerkt door statische bestands-middleware voordat middleware voor reactiecompressie wordt verwerkt. 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 middleware eerst te laten reageren op overeenkomende aanvragen.
- Om SPA's met client-side-routering te laten werken voor alle routes die de servertoepassing niet herkent.
Zie de handleidingen voor de projectsjablonen React en Angular voor meer informatie over SPA's.
Zie de handleidingen voor de projectsjablonen React en Angular voor informatie over toepassingen met één pagina.
UseCors en UseStaticFiles bestellen
Voor meer informatie over het bestellen van UseCors en UseStaticFiles, zie CORS (Cross-Origin Requests) inschakelen in ASP.NET Core.
Volgorde van de middleware voor doorgestuurde headers
Voer de middleware voor doorgestuurde headers uit vóór andere middleware, zodat middleware die afhankelijk is van informatie uit doorgestuurde headers de headerwaarden kan gebruiken bij de verwerking. Zie de volgorde van de middleware voor doorgestuurde headers als u de middleware voor doorgestuurde headers wilt uitvoeren na middleware voor diagnostiek en foutafhandeling.
Ingebouwde middleware
De nieuwste versie van ASP.NET Core bevat de volgende middleware. De kolom UI-stack toont de typische UI-stack waarin de middleware wordt gebruikt: [Alle, Blazor Web App (BWA), Razor Pagina's en MVC (RP/MVC)]. De kolom Order bevat notities over de plaatsing van middleware in de aanvraagverwerkingspijplijn en onder welke omstandigheden de middleware de verwerking van aanvragen kan stoppen. Wanneer een middleware de aanvraagverwerkingspijplijn kortcircuitt en voorkomt dat verdere downstream-middleware een aanvraag verwerkt, wordt dit een terminal-middlewaregenoemd. Zie voor meer informatie over kortsluiten de sectie Een middlewarepijplijn maken met WebApplication.
| Middleware | Beschrijving | UI-stack | Bevelen |
|---|---|---|---|
| Antiforgerie | Biedt ondersteuning voor anti-aanvraagvervalsing. | All | Na authenticatie en autorisatie, vóór eindpunten. |
| verificatie | Biedt ondersteuning voor verificatie. | All | Voordat HttpContext.User vereist is. Terminal voor OAuth-callbacks. |
| autorisatie | Biedt autorisatieondersteuning. | All | Direct na de authenticatiemiddleware. |
| Cookie Beleid | Houdt toestemming van gebruikers bij voor het opslaan van persoonlijke gegevens en dwingt minimumstandaarden af voor cookie velden, zoals secure en SameSite. |
All | Voordat de middleware cookies uitgeeft. Voorbeelden: verificatie, sessie, MVC (TempData). |
| CORS | Hiermee wordt Cross-Origin Resource Sharing geconfigureerd. | All | Vóór middleware dat gebruikmaakt van CORS.
UseCors moet eerder dan UseResponseCaching gaan. Zie Het is niet duidelijk dat UseCORS vóór UseResponseCaching (dotnet/aspnetcore #23218) moet komen voor meer informatie. |
| uitzonderingspagina voor ontwikkelaars | Hiermee wordt een pagina gegenereerd met foutinformatie die alleen is bedoeld voor gebruik in de Development omgeving. |
All | Voordat middleware fouten genereren. De projectsjablonen registreren deze middleware automatisch als de eerste middleware in de pijplijn wanneer de omgeving is Development. |
| Diagnostische gegevens | Verschillende afzonderlijke middlewares die een uitzonderingspagina voor ontwikkelaars bieden, uitzonderingsafhandeling, statuscodepagina's en de standaardwebpagina voor nieuwe apps. | All | Voordat middleware fouten 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. | All | Voordat middleware de bijgewerkte velden verwerken. 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. | All | 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. | ||
| All | |||
| HTTP-logboekregistratie | Registreert HTTP-aanvragen en -antwoorden. | All | Aan het begin van de middleware-pijplijn. |
| HTTP-methode overschrijven | Hiermee kan een binnenkomende POST-aanvraag de methode overschrijven. | All | Voordat middleware de bijgewerkte methode benut. |
| HTTPS-omleiding | Alle HTTP-aanvragen worden omgeleid naar HTTPS. | All | Voordat middleware de URL gebruikt. |
| HTTP Strict Transport Security (HSTS) | Middleware voor beveiligingsverbeteringen waarmee een speciale antwoordheader wordt toegevoegd. | All | Vóór het verzenden van antwoorden en ná de middleware die aanvragen wijzigt. Voorbeelden: Doorgestuurde headers, URL-herschrijven. |
| MVC | Verwerkt aanvragen met MVC en Razor Pages. | RP/MVC | Terminal als een aanvraag overeenkomt met een route. |
| OWIN | Interoperabiliteit met op OWIN gebaseerde apps, servers en middleware. | RP/MVC | 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. | RP/MVC | Voordat middleware wordt opgeslagen waarvoor caching is vereist. UseRouting, UseCors, UseAuthentication en UseAuthorization moeten vóór UseOutputCache komen. |
| Antwoordcaching | Biedt ondersteuning voor het opslaan van antwoorden in cache. Deze middleware vereist dat clientdeelname werkt. Gebruik uitvoercache voor volledig serverbeheer. | RP/MVC | Voordat middleware wordt opgeslagen waarvoor caching is vereist. UseCors moet vóór UseResponseCachingkomen. Het opslaan van reacties in de cache 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. | All | Voordat middleware het aanvraaglichaam leest. |
| Antwoordcompressie | Biedt ondersteuning voor het comprimeren van antwoorden. | All | Vóór middleware waarvoor compressie is vereist. |
| Verzoek om lokalisatie | Biedt lokalisatieondersteuning. | All | Vóór lokalisatie gevoelige middleware. Moet na de routeringsmiddleware staan bij gebruik van RouteDataRequestCultureProvider. |
| Time-outs voor verzoeken | Biedt ondersteuning voor het configureren van time-outs voor aanvragen, globaal en per eindpunt. | All | UseRequestTimeouts moet na UseExceptionHandler, UseDeveloperExceptionPageen UseRoutingkomen. |
| Eindpuntroutering. | Hiermee definieert en beperkt u aanvraagroutes. | All | 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. | All | Verschijnt laat in de pijplijn, waardoor andere middleware voor het dienen van statische bestanden, zoals MVC-acties, voorrang hebben. |
| sessie | Biedt ondersteuning voor het beheren van gebruikerssessies. | RP/MVC | Voordat middleware dat een sessie vereist. |
| Statisch bestand | Biedt ondersteuning voor het leveren van statische bestanden en bladeren door mappen. | All | Terminal als een aanvraag overeenkomt met een bestand. |
| URL herschrijven | Biedt ondersteuning voor het herschrijven van URL's en het omleiden van aanvragen. | All | Voordat middleware de URL gebruikt. |
| W3C-logboekregistratie | Genereert servertoegangslogboeken in de uitgebreide W3C-logboekindeling. | All | Aan het begin van de middleware-pijplijn. |
| Blazor WebAssembly Foutopsporing | Fouten opsporen Blazor Web Appdie gebruikmaken van client-side rendering (CSR) in Chromium-ontwikkelhulpprogramma's. | BWA | Aan het begin van de middleware-pijplijn. |
| WebSockets | Hiermee schakelt u het WebSockets-protocol in. | All | Voor de middleware die vereist is om WebSocket-aanvragen te accepteren. |
Aanvullende informatiebronnen
- Opties voor levensduur en registratie (inclusief middleware-voorbeeld)
- Aangepaste ASP.NET Core-middleware schrijven
- ASP.NET Core-middleware testen
- gRPC-Web configureren in ASP.NET Core
- HTTP-modules migreren naar ASP.NET Core-middleware
- app opstarten in ASP.NET Core
- -aanvraagfuncties in ASP.NET Core-
- Middlewareactivering gebaseerd op factory in ASP.NET Core
- Middleware-activering met een container van derden in ASP.NET Core
- Overzicht van API's