ASP.NET Core Middleware
Anteckning
Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i den .NET 9-versionen av den här artikeln.
Varning
Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy. Den aktuella versionen finns i den .NET 9-versionen av den här artikeln.
Viktig
Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.
Den aktuella versionen finns i den .NET 9-versionen av den här artikeln.
Av Rick Anderson och Steve Smith
Mellanprogram är programvara som monteras i en apppipeline för att hantera begäranden och svar. Varje komponent:
- Väljer om begäran ska skickas till nästa komponent i pipelinen.
- Kan utföra arbete före och efter nästa komponent i pipelinen.
Begärandedelegater används för att bygga begärandepipelinen. Begärandedelegaterna hanterar varje HTTP-begäran.
Delegater för förfrågningar konfigureras med Run, Mapoch Use tilläggsmetoder. Ett ombud för enskilda begäranden kan anges in-line som en anonym metod (kallas in-line middleware) eller definieras i en återanvändbar klass. Dessa återanvändbara klasser och inbyggda anonyma metoder är mellanlager, även kallade mellanlagerkomponenter. Varje mellanprogramskomponent i begärandepipelinen ansvarar för att anropa nästa komponent i pipelinen eller kortsluta pipelinen. När ett mellanprogram kortsluts kallas det för ett terminalmellanprogram eftersom det förhindrar att ytterligare mellanprogram bearbetar begäran.
Migrera HTTP-hanterare och moduler till ASP.NET Core-mellanprogram förklarar skillnaden mellan pipelines för begäran i ASP.NET Core och ASP.NET 4.x och innehåller ytterligare mellanprogramsexempel.
Rollen mellanprogram efter apptyp
Blazor Web Apps, Razor Pages och MVC bearbetar webbläsarbegäranden på servern med mellanprogram. Vägledningen i den här artikeln gäller för dessa typer av appar.
Fristående Blazor WebAssembly appar körs helt på klienten och bearbetar inte begäranden med en pipeline för mellanprogram. Vägledningen i den här artikeln gäller inte för fristående Blazor WebAssembly appar.
Kodanalys för mellanprogram
ASP.NET Core innehåller många analysverktyg för kompilatorns plattform som kontrollerar programkoden för kvalitet. Mer information finns i Code-analys i ASP.NET Core-appar
Skapa en pipeline för mellanprogram med WebApplication
Pipelinen ASP.NET Core-begäran består av en sekvens med begärandedelegater som anropas en efter en. Följande diagram visar konceptet. Körningstråden följer de svarta pilarna.
Varje ombud kan utföra åtgärder före och efter nästa ombud. Ombud för undantagshantering bör anropas tidigt i pipelinen, så att de kan fånga upp undantag som inträffar i senare skeden av pipelinen.
Den enklaste möjliga ASP.NET Core-appen konfigurerar ett ombud för en enda begäran som hanterar alla begäranden. Det här fallet innehåller inte en verklig begärandepipeline. I stället anropas en enda anonym funktion som svar på varje HTTP-begäran.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
app.Run();
Länka flera ombud för förfrågningar tillsammans med Use. Parametern next
representerar nästa ombud i pipelinen. Du kan kortsluta pipelinen genom att inte anropa parametern next
. Du kan vanligtvis utföra åtgärder både före och efter delegaten next
, vilket demonstreras i följande exempel:
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();
Kortsluta pipelinen för begäran
När ett ombud inte skickar en begäran till nästa ombud kallas det kortsluta begärandepipelinen. Kortslutning är ofta önskvärt eftersom det undviker onödigt arbete. Till exempel kan Static File Middleware fungera som ett terminalmellanprogram genom att bearbeta en begäran om en statisk fil och kortsluta pipelinens rest. Mellanprogram som lagts till i pipelinen innan mellanprogrammet som avslutar ytterligare bearbetning bearbetar fortfarande kod efter deras next.Invoke
-instruktioner. Se dock följande varning om att försöka skriva till ett svar som redan har skickats.
Varning
Anropa inte next.Invoke
under eller efter att svaret har skickats till klienten. När en HttpResponse har startat resulterar ändringar i ett undantag. Till exempel inställningshuvuden och en statuskod utlöser ett undantag när svaret startar. Att skriva till svarstexten efter att ha anropat next
:
- Kan orsaka en protokollöverträdelse, till exempel att skriva mer än den angivna
Content-Length
. - Kan skada brödtextformatet, till exempel skriva en HTML-sidfot till en CSS-fil.
HasStarted är ett användbart tips för att ange om rubriker har skickats eller om brödtexten har skrivits till.
Mer information finns i Kortslutning mellanprogram efter routning.
Run
ombud
Run ombud får ingen next
parameter. Det första Run
ombudet är alltid terminalen och avslutar pipelinen.
Run
är en konvention. Vissa mellanprogramskomponenter kan exponera Run[Middleware]
metoder som körs i slutet av pipelinen:
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();
Om du vill se kodkommentar översatta till andra språk än engelska kan du meddela oss i det här GitHub-diskussionsproblemet.
I föregående exempel skriver Run
-ombudet "Hello from 2nd delegate."
till svaret och avslutar sedan pipelinen. Om en annan Use
- eller Run
-ombud läggs till efter Run
-ombudet, så anropas det inte.
Föredrar app. Använd överlagring som kräver att kontexten skickas till nästa
Den appen som inte allokeras. Använd tilläggsmetod:
- Kräver att kontexten skickas till
next
. - Sparar två interna allokeringar per förfrågan som krävs när du använder den andra överbelastningen.
Mer information finns i det här GitHub-problemet.
Mellanprogramvarubeställning
Följande diagram visar den fullständiga pipelinen för bearbetning av begäranden för ASP.NET Core MVC- och Razor Pages-appar. Du kan se hur befintliga mellanprogram sorteras i en typisk app och var anpassade mellanprogram läggs till. Du har fullständig kontroll över hur du ändrar ordning på befintliga mellanprogram eller matar in nya anpassade mellanprogram efter behov för dina scenarier.
Endpoint-middleware i föregående diagram kör filterpipelinen för motsvarande apptyp – MVC eller Razor Pages.
Routning mellanprogram i föregående diagram visas efter Static Files. Det här är den ordning som projektmallarna implementerar genom att uttryckligen anropa app. UseRouting. Om du inte anropar app.UseRouting
körs Routning mellanprogram i början av pipelinen som standard. För mer information, se Routing.
Ordningen som mellanprogramkomponenter läggs till i filen Program.cs
definierar i vilken ordning mellanprogramkomponenterna anropas på begäranden och omvänd ordning för svaret. Ordningen är kritisk för säkerhet, prestanda och funktioner.
Följande markerade kod i Program.cs
lägger till säkerhetsrelaterade mellanprogramskomponenter i den vanliga rekommenderade ordningen:
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();
I föregående kod:
- Mellanprogramvara som inte läggs till när du skapar en ny webbapp med enskilda användarkonton kommenteras ut.
- Inte alla mellanprogram visas i den här exakta ordningen, men många gör det. Till exempel:
-
UseCors
,UseAuthentication
ochUseAuthorization
måste visas i den ordning som visas. -
UseCors
måste för närvarande visas innanUseResponseCaching
. Det här kravet förklaras i GitHub-problem med dotnet/aspnetcore #23218. -
UseRequestLocalization
måste visas före alla mellanprogram som kan kontrollera begärandekulturen, till exempelapp.UseStaticFiles()
. -
UseRateLimiter måste anropas efter
UseRouting
när hastighetsbegränsning av slutpunktsspecifika API:er används. Om attributet[EnableRateLimiting]
till exempel används måsteUseRateLimiter
anropas efterUseRouting
. När du bara anropar globala begränsare kanUseRateLimiter
anropas innanUseRouting
.
-
I vissa scenarier har mellanprogram olika sortering. Cachelagring och komprimeringsordning är till exempel scenariospecifika, och det finns flera giltiga ordningar. Till exempel:
app.UseResponseCaching();
app.UseResponseCompression();
Med föregående kod kan cpu-användningen minskas genom cachelagring av det komprimerade svaret, men du kan komma att cachelagra flera representationer av en resurs med hjälp av olika komprimeringsalgoritmer som Gzip eller Brotli.
Följande ordning kombinerar statiska filer för att tillåta cachelagring av komprimerade statiska filer:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();
Följande Program.cs
kod lägger till mellanprogramskomponenter för vanliga appscenarier:
- Undantags-/felhantering
- När appen körs i utvecklingsmiljön:
- Developer Exception Page Middleware (UseDeveloperExceptionPage) rapporterar appkörningsfel.
- Database Error Page Middleware (UseDatabaseErrorPage) rapporterar databaskörningsfel.
- När appen körs i produktionsmiljön:
- Undantagshanterarens mellanprogram (UseExceptionHandler) fångar undantag som genereras i följande mellanprogram.
- HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) lägger till
Strict-Transport-Security
-huvudet.
- När appen körs i utvecklingsmiljön:
- HTTPS Redirection Middleware (UseHttpsRedirection) omdirigerar HTTP-begäranden till HTTPS.
- Static File Middleware (UseStaticFiles) returnerar statiska filer och avbryter fortsatt bearbetning av begäranden.
- Cookie Policy Middleware (UseCookiePolicy) överensstämmer med eu:s allmänna dataskyddsförordning (GDPR).
- Routning av mellanprogram (UseRouting) för att dirigera begäranden.
- Autentisering mellanprogram (UseAuthentication) försöker autentisera användaren innan de får åtkomst till säkra resurser.
- Authorization Middleware (UseAuthorization) ger en användare åtkomst till säkra resurser.
- Sessionsmellanprogram (UseSession) upprättar och underhåller sessionstillstånd. Om appen använder sessionstillstånd, anropar du Sessionsmellanprogram efter Cookie Policy-mellanprogram och före MVC-mellanprogram.
- Slutpunktsdirigering mellanprogram (UseEndpoints med MapRazorPages) för att lägga till Razor Pages-slutpunkter i förfrågningsflödet.
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();
I föregående exempelkod exponeras varje mellanprogramstilläggsmetod på WebApplicationBuilder via Microsoft.AspNetCore.Builder namnrymd.
UseExceptionHandler är den första mellanprogramskomponenten som läggs till i pipelinen. Därför fångar undantagshanterarens mellanprogram alla undantag som inträffar i senare anrop.
Static File Middleware anropas tidigt i pipelinen så att den kan hantera begäranden och kortslutning utan att gå igenom de återstående komponenterna. Mellanprogrammet för statiska filer ger inga auktoriseringskontroller. Alla filer som hanteras av Static File Middleware, inklusive de under wwwroot, är offentligt tillgängliga. En metod för att skydda statiska filer finns i Statiska filer i ASP.NET Core.
Om begäran inte hanteras av den statiska filmellanprogrammet skickas den vidare till autentiseringsmellanprogrammet (UseAuthentication), som utför autentisering. Autentisering kortsluter inte oautentiserade begäranden. Även om autentiserings-mellanprogram autentiserar begäranden sker auktorisering (och avvisande) endast efter att MVC har valt en specifik Razor-sida eller MVC-kontroller och metod.
I följande exempel visas en mellanprogramsordning där begäranden om statiska filer hanteras av Static File Middleware före Mellanprogram för svarskomprimering. Statiska filer komprimeras inte med den här mellanprogramsordningen. Svar på sidor Razor kan komprimeras.
// Static files aren't compressed by Static File Middleware.
app.UseStaticFiles();
app.UseRouting();
app.UseResponseCompression();
app.MapRazorPages();
Information om ensidesprogram finns i Översikt över ensidesappar (SPA) i ASP.NET Core.
UseCors- och UseStaticFiles-ordning
Ordningen för att anropa UseCors
och UseStaticFiles
beror på appen. Mer information finns i UseCors- och UseStaticFiles-order
Mellanprogramsordning för vidarebefordrade rubriker
Vidarebefordrade rubriker Mellanprogram ska köras före andra mellanprogram. Den här ordningen säkerställer att mellanprogrammet som förlitar sig på vidarebefordrad rubrikinformation kan använda huvudvärdena för bearbetning. Information om hur du kör vidarebefordrade headers-mellanprogram efter diagnostik- och felhanteringsmellanprogram finns i Vidarebefordrade headers-mellanprogramsordning.
Förgrena pipelinen för mellanprogram
Map tillägg används som en konvention för att förgrena pipelinen.
Map
förgrenar pipelinen för begäran baserat på matchningar av den angivna sökvägen för begäran. Om sökvägen för begäran börjar med den angivna sökvägen körs grenen.
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");
});
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod.
Begäran | Svar |
---|---|
localhost:1234 | Hej från en icke-Map-delegat. |
localhost:1234/map1 | Karttest 1 |
localhost:1234/map2 | Karttest 2 |
localhost:1234/map3 | Hej från ombud utan koppling till Map. |
När Map
används tas de matchade sökvägssegmenten bort från HttpRequest.Path
och läggs till i HttpRequest.PathBase
för varje begäran.
Map
stöder kapsling, till exempel:
app.Map("/level1", level1App => {
level1App.Map("/level2a", level2AApp => {
// "/level1/level2a" processing
});
level1App.Map("/level2b", level2BApp => {
// "/level1/level2b" processing
});
});
Map
kan också matcha flera segment samtidigt:
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 förgrenar pipelinen för begäran baserat på resultatet av det angivna predikatet. Alla predikat av typen Func<HttpContext, bool>
kan användas för att mappa begäranden till en ny gren av pipelinen. I följande exempel används ett predikat för att identifiera förekomsten av en frågesträngsvariabel 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}");
});
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod:
Begäran | Svar |
---|---|
localhost:1234 |
Hello from non-Map delegate. |
localhost:1234/?branch=main |
Branch used = main |
UseWhen förgrenar även pipelinen för begäran baserat på resultatet av det angivna predikatet. Till skillnad från med MapWhen
återansluts den här grenen till huvudpipelinen om den inte innehåller något terminalmellanprogram:
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.
});
}
I föregående exempel skrivs ett svar av Hello from non-Map delegate.
för alla begäranden. Om begäran innehåller en frågesträngsvariabel branch
loggas dess värde innan huvudpipelinen återansluts.
Inbyggda mellanprogram
ASP.NET Core levereras med följande mellanprogramkomponenter. Kolumnen Order innehåller anteckningar om mellanprogramsplacering i pipelinen för bearbetning av begäranden och under vilka villkor mellanprogrammet kan avsluta bearbetningen av begäranden. När ett mellanprogram kortsluter pipelinen för bearbetning av begäranden och hindrar ytterligare underordnade mellanprogram från att bearbeta en begäran kallas det för en terminalmellanprogram. Mer information om kortslutning finns i avsnittet Skapa en pipeline för mellanprogram med WebApplication.
Mellanprogram | Beskrivning | Ordning |
---|---|---|
autentisering | Tillhandahåller autentiseringsstöd. | Innan HttpContext.User behövs. Terminal för återanrop till OAuth. |
auktorisering | Tillhandahåller auktoriseringsstöd. | Omedelbart efter autentiseringsmellanprogrammet. |
Cookie policy | Spårar medgivande från användare för lagring av personlig information och tillämpar minimistandarder för cookie fält, till exempel secure och SameSite . |
Före mellanliggande programvara som utfärdar cookies. Exempel: Autentisering, Session, MVC (TempData). |
CORS | Konfigurerar resursdelning mellan ursprung. | Före komponenter som använder CORS.
UseCors måste för närvarande gå före UseResponseCaching på grund av den här buggen. |
DeveloperExceptionPage | Genererar en sida med felinformation som endast är avsedd att användas i utvecklingsmiljön. | Före komponenter som genererar fel. Projektmallarna registrerar automatiskt detta middleware som det första i pipelinen när miljön är Development. |
Diagnostik | Flera separata mellanprogram som tillhandahåller en undantagssida för utvecklare, undantagshantering, statuskodsidor och standardwebbsidan för nya appar. | Före komponenter som genererar fel. Terminal för undantagshantering eller visar standardwebbsidan för nya appar. |
vidarebefordrade rubriker | Vidarebefordrar proxy-headers till den aktuella begäran. | Före de komponenter som använder de uppdaterade fälten. Exempel: schema, värd, klient-IP, metod. |
hälsokontroll | Kontrollerar hälsotillståndet för en ASP.NET Core-app och dess beroenden, till exempel att kontrollera databasens tillgänglighet. | Terminal om en begäran matchar en slutpunkt för hälsokontroll. |
Rubrik Spridning | Sprider HTTP-huvuden från den inkommande begäran till utgående HTTP-klientbegäranden. | |
HTTP-loggning | Loggar HTTP-begäranden och svar. | I början av pipelinen för mellanprogram. |
åsidosättning av HTTP-metod | Tillåter att en inkommande POST-begäran åsidosätter metoden. | Före komponenter som använder den uppdaterade metoden. |
HTTPS-omdirigering | Omdirigera alla HTTP-begäranden till HTTPS. | Före komponenter som använder URL:en. |
HTTP Strict Transport Security (HSTS) | Mellanprogram för säkerhetsförbättringar som lägger till ett särskilt svarshuvud. | Innan svar skickas och efter komponenter som ändrar begäranden. Exempel: Vidarebefordrade rubriker, URL-omskrivning. |
MVC | Bearbetar begäranden med MVC/Razor Pages. | Slutpunkt när en förfrågan matchar en rutt. |
OWIN | Interop med OWIN-baserade appar, servrar och mellanprogram. | Terminal om OWIN Middleware fullständigt bearbetar begäran. |
cachelagring av utdata | Ger stöd för cachelagringssvar baserat på konfiguration. | Före komponenter som kräver cachelagring.
UseRouting måste komma före UseOutputCaching .
UseCORS måste komma före UseOutputCaching . |
cachelagring av svar | Ger stöd för cachelagring av svar. Detta kräver att klienten deltar i arbetet. Använd cachelagring av utdata för fullständig serverkontroll. | Före komponenter som kräver cachelagring.
UseCORS måste komma före UseResponseCaching . Är vanligtvis inte fördelaktigt för användargränssnittsappar som Razor Pages eftersom webbläsare vanligtvis anger begärandehuvuden som förhindrar cachelagring.
Cachelagring av utdata gynnar användargränssnittsappar. |
Begär dekomprimering | Ger stöd för dekomprimering av begäranden. | Före komponenter som läser begärandetexten. |
komprimering av svar | Ger stöd för att komprimera svar. | Före komponenter som kräver komprimering. |
Begär lokaliseringsförfrågan | Tillhandahåller lokaliseringsstöd. | Före lokalisering av känsliga komponenter. Måste visas efter routning av mellanprogram när du använder RouteDataRequestCultureProvider. |
Tidsgränser för begäranden | Ger stöd för att konfigurera tidsgränser för begäranden, globala och per slutpunkt. |
UseRequestTimeouts måste komma efter UseExceptionHandler , UseDeveloperExceptionPage och UseRouting . |
Slutpunktsroutning | Definierar och begränsar begärandevägar. | Terminal för matchande rutter. |
SPA | Hanterar alla begäranden från den här punkten i mellanprogramskedjan genom att returnera standardsidan för spa-programmet (Single Page Application) | Sent i kedjan, så att andra mellanprogram för att hantera statiska filer, MVC-åtgärder osv. har företräde. |
Session | Ger stöd för hantering av användarsessioner. | Före komponenter som kräver Session. |
Statiska filer | Ger stöd för att hantera statiska filer och katalogbläddring. | Terminal om en begäran matchar en fil. |
URL-omskrivning | Ger stöd för att skriva om URL:er och omdirigera begäranden. | Före komponenter som använder URL:en. |
W3CLogging | Genererar serveråtkomstloggar i W3C Extended Log File Format. | I början av pipelinen för mellanprogram. |
WebSockets | Aktiverar WebSockets-protokollet. | Innan komponenter som krävs för att acceptera WebSocket-begäranden. |
Ytterligare resurser
- Alternativ för livslängd och registrering innehåller ett fullständigt exempel på mellanprogram med begränsade, tillfälligaoch singleton- livslängdstjänster.
- Skriva anpassade ASP.NET Core-mellanprogram
- Testa ASP.NET Core-mellanprogram
- Konfigurera gRPC-Web i ASP.NET Core
- Migrera HTTP-hanterare och -moduler till ASP.NET Core-mellanprogram
- Start av applikation i ASP.NET Core
- begär funktioner i ASP.NET Core
- Fabriksbaserad aktivering av mellanprogram i ASP.NET Core
- Mellanprogramsaktivering med en tredjepartscontainer i ASP.NET Core
Av Rick Anderson och Steve Smith
Mellanprogram är programvara som monteras i en apppipeline för att hantera begäranden och svar. Varje komponent:
- Väljer om begäran ska skickas till nästa komponent i pipelinen.
- Kan utföra arbete före och efter nästa komponent i pipelinen.
Begärandedelegater används för att bygga begärandepipelinen. Begärandedelegaterna hanterar varje HTTP-begäran.
Begärandeombud konfigureras med hjälp av Run, Mapoch Use förlängningsmetoder. Ett ombud för enskilda begäranden kan anges in-line som en anonym metod (kallas in-line middleware) eller definieras i en återanvändbar klass. Dessa återanvändbara klasser och in-line anonyma metoder är mellanprogram, kallas även mellanprogramskomponenter. Varje mellanprogramskomponent i begärandepipelinen ansvarar för att anropa nästa komponent i pipelinen eller kortsluta pipelinen. När ett mellanprogram kortsluts kallas det för ett terminalmellanprogram eftersom det förhindrar att ytterligare mellanprogram bearbetar begäran.
Migrera HTTP-hanterare och moduler till ASP.NET Core-mellanprogram förklarar skillnaden mellan pipelines för begäran i ASP.NET Core och ASP.NET 4.x och innehåller ytterligare mellanprogramsexempel.
Rollen mellanprogram efter apptyp
Razor Pages, MVC, Blazor Serveroch projektet på serversidan för en värdbaserad Blazor WebAssembly lösning bearbetar webbläsarbegäranden på servern med mellanprogram. Vägledningen i den här artikeln gäller för dessa typer av appar.
Fristående Blazor WebAssembly appar körs helt på klienten och bearbetar inte begäranden med en pipeline för mellanprogram. Vägledningen i den här artikeln gäller inte för fristående Blazor WebAssembly appar.
Kodanalys för mellanprogram
ASP.NET Core innehåller många analysverktyg för kompilatorns plattform som kontrollerar programkoden för kvalitet. Mer information finns i Code-analys i ASP.NET Core-appar
Skapa en pipeline för mellanprogram med WebApplication
Begärningspipeline för ASP.NET Core består av en sekvens med begärandedelegater som anropas en i taget. Följande diagram visar konceptet. Exekveringstråden följer de svarta pilarna.
Varje ombud kan utföra åtgärder före och efter nästa ombud. Ombud för undantagshantering bör anropas tidigt i pipelinen, så att de kan fånga upp undantag som inträffar i senare skeden av pipelinen.
Den enklaste möjliga ASP.NET Core-appen konfigurerar ett ombud för en enda begäran som hanterar alla begäranden. Det här fallet innehåller inte en pipeline för verkliga förfrågningar. I stället anropas en enda anonym funktion som svar på varje HTTP-begäran.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
app.Run();
Länka flera förfrågningsdelegater med Use. Parametern next
representerar nästa ombud i pipelinen. Du kan kortsluta pipelinen genom att inte anropa parametern next
. Du kan vanligtvis utföra åtgärder både före och efter deleger next
, vilket visas i följande exempel:
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();
När ett ombud inte skickar en begäran vidare till nästa ombud kallas det avbryta begärandepipelinen. Kortslutning är ofta önskvärt eftersom det undviker onödigt arbete. Till exempel kan Static File Middleware fungera som ett terminalmellanprogram genom att bearbeta en begäran om en statisk fil och kortsluta pipelinens rest. Mellanprogram som lagts till i pipelinen innan mellanprogrammet som avslutar ytterligare bearbetning bearbetar fortfarande kod efter deras next.Invoke
-instruktioner. Se dock följande varning om att försöka skriva till ett svar som redan har skickats.
Varning
Anropa inte next.Invoke
när svaret har skickats till klienten. Ändringar i HttpResponse när svaret har börjat generera ett undantag. Till exempel inställningshuvuden och en statuskod utlöser ett undantag. Skriva till svarskroppen efter att ha kallat på next
:
- Kan orsaka en protokollöverträdelse. Du kan till exempel skriva mer än den angivna
Content-Length
. - Kan skada brödtextformatet. Du kan till exempel skriva en HTML-sidfot till en CSS-fil.
HasStarted är ett användbart tips för att ange om rubriker har skickats eller om brödtexten har skrivits till.
Run ombud får ingen next
parameter. Det första Run
-delegeringen är alltid terminal och avslutar rörledningen.
Run
är en konvention. Vissa mellanprogramskomponenter kan exponera Run[Middleware]
metoder som körs i slutet av pipelinen:
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();
Om du vill se kodkommentar översatta till andra språk än engelska kan du meddela oss i det här GitHub-diskussionsproblemet.
I föregående exempel skriver Run
-ombudet "Hello from 2nd delegate."
till svaret och avslutar sedan pipelinen. Om en annan Use
eller Run
ombud läggs till efter Run
ombud anropas det inte.
Föredrar app. Använd överlagring som kräver att kontexten skickas till nästa
Den appen som inte allokeras. Använd tilläggsmetod:
- Kräver att kontexten skickas till
next
. - Sparar två interna tilldelningar per begäran som krävs vid användning av den andra överbelastningen.
Mer information finns i det här GitHub-ärendet.
Middleware-beställning
Följande diagram visar den fullständiga pipelinen för bearbetning av begäranden för ASP.NET Core MVC- och Razor Pages-appar. Du kan se hur befintliga mellanprogram sorteras i en typisk app och var anpassade mellanprogram läggs till. Du har fullständig kontroll över hur du ändrar ordning på befintliga mellanprogram eller matar in nya anpassade mellanprogram efter behov för dina scenarier.
Slutpunkt mellanprogram i föregående diagram kör filterpipelinen för motsvarande apptyp – MVC eller Razor Pages.
Routning mellanprogrammet i det föregående diagrammet visas efter statiska filer. Det här är den ordning som projektmallarna implementerar genom att uttryckligen anropa app. UseRouting. Om du inte anropar app.UseRouting
körs routning mellanprogrammet i början av pipelinen som standard. Mer information finns i Ruttning.
Ordningen som mellanprogramkomponenter läggs till i filen Program.cs
definierar i vilken ordning mellanprogramkomponenterna anropas på begäranden och omvänd ordning för svaret. Ordningen är kritisk för säkerhet, prestanda och funktioner.
Följande markerade kod i Program.cs
lägger till säkerhetsrelaterade mellanprogramskomponenter i den vanliga rekommenderade ordningen:
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();
I föregående kod:
- Mellanprogram som inte läggs till när du skapar en ny webbapp med enskilda användarkonton kommenteras ut.
- Inte alla mellanprogram visas i den här exakta ordningen, men många gör det. Till exempel:
-
UseCors
,UseAuthentication
ochUseAuthorization
måste visas i den ordning som visas. -
UseCors
måste för närvarande visas innanUseResponseCaching
. Det här kravet förklaras i GitHub-ärende dotnet/aspnetcore #23218. -
UseRequestLocalization
måste visas före alla mellanprogram som kan kontrollera begärandekulturen, till exempelapp.UseStaticFiles()
. -
UseRateLimiter måste anropas efter
UseRouting
när hastighetsbegränsning av slutpunktsspecifika API:er används. Om attributet[EnableRateLimiting]
till exempel används måsteUseRateLimiter
anropas efterUseRouting
. När du bara anropar globala begränsare kanUseRateLimiter
anropas innanUseRouting
.
-
I vissa scenarier har mellanprogram olika sortering. Cachelagring och komprimeringsordning är till exempel scenariospecifika, och det finns flera giltiga ordningar. Till exempel:
app.UseResponseCaching();
app.UseResponseCompression();
Med föregående kod kan cpu-användningen minskas genom cachelagring av det komprimerade svaret, men du kan komma att cachelagra flera representationer av en resurs med hjälp av olika komprimeringsalgoritmer som Gzip eller Brotli.
Följande ordning kombinerar statiska filer för att tillåta cachelagring av komprimerade statiska filer:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();
Följande Program.cs
kod lägger till mellanprogramskomponenter för vanliga appscenarier:
- Undantags-/felhantering
- När appen körs i utvecklingsmiljön:
- Developer Exception Page Middleware (UseDeveloperExceptionPage) rapporterar appkörningsfel.
- Database Error Page Middleware (UseDatabaseErrorPage) rapporterar databaskörningsfel.
- När appen körs i produktionsmiljön:
- Undantagshanterarens mellanprogram (UseExceptionHandler) fångar undantag som genereras i följande mellanprogram.
- HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) lägger till
Strict-Transport-Security
-huvudet.
- När appen körs i utvecklingsmiljön:
- HTTPS Redirection Middleware (UseHttpsRedirection) omdirigerar HTTP-begäranden till HTTPS.
- Static File Middleware (UseStaticFiles) returnerar statiska filer och bryter ytterligare bearbetning av begäranden.
- Cookie Policy Middleware (UseCookiePolicy) överensstämmer med eu:s allmänna dataskyddsförordning (GDPR).
- Routning av mellanprogram (UseRouting) för att dirigera begäranden.
- Autentisering mellanprogram (UseAuthentication) försöker autentisera användaren innan de får åtkomst till säkra resurser.
- Authorization Middleware (UseAuthorization) ger en användare åtkomst till säkra resurser.
- Sessionsmellanprogram (UseSession) upprättar och underhåller sessionstillstånd. Om appen använder sessionstillstånd anropar du Sessionsmellanprogram efter Cookie principmellanprogram och före MVC Middleware.
- Slutpunktsdirigering mellanprogram (UseEndpoints med MapRazorPages) för att lägga till Razor Pages-slutpunkter i begärandepipelinen.
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();
I föregående exempelkod exponeras varje mellanprogramstilläggsmetod på WebApplicationBuilder via Microsoft.AspNetCore.Builder namnrymd.
UseExceptionHandler är den första mellanprogramskomponenten som läggs till i pipelinen. Därför fångar undantagshanterarens mellanprogram alla undantag som inträffar i senare anrop.
Static File Middleware anropas tidigt i pipelinen så att den kan hantera begäranden och kortslutning utan att gå igenom de återstående komponenterna. Mellanprogrammet för statiska filer ger inga auktoriseringskontroller. Alla filer som hanteras av Static File Middleware, inklusive de under wwwroot, är offentligt tillgängliga. En metod för att skydda statiska filer finns i Statiska filer i ASP.NET Core.
Om begäran inte hanteras av den statiska filmellanprogrammet skickas den vidare till autentiseringsmellanprogrammet (UseAuthentication), som utför autentisering. Autentisering kortsluter inte oautentiserade begäranden. Även om autentiserings-mellanprogram autentiserar begäranden, sker auktorisering (och avvisande) först efter att MVC har valt en specifik Razor-sida eller MVC-controller och åtgärd.
I följande exempel visas en mellanprogramsordning där begäranden om statiska filer hanteras av Static File Middleware före Mellanprogram för svarskomprimering. Statiska filer komprimeras inte med den här mellanprogramsordningen. Svar på Razor-sidorna kan komprimeras.
// Static files aren't compressed by Static File Middleware.
app.UseStaticFiles();
app.UseRouting();
app.UseResponseCompression();
app.MapRazorPages();
Information om ensidesprogram finns i guiderna för projektmallarna React och Angular.
UseCors- och UseStaticFiles-ordning
Ordningen för att anropa UseCors
och UseStaticFiles
beror på appen. Mer information finns i UseCors- och UseStaticFiles-order
Mellanprogramsordning för vidarebefordrade rubriker
Vidarebefordrade headers mellanprogram ska köras före andra mellanprogram. Den här ordningen säkerställer att mellanprogrammet som förlitar sig på vidarebefordrad rubrikinformation kan använda huvudvärdena för bearbetning. För att köra Vidarebefordrade rubriker-mellanprogrammet efter diagnostik- och felhanteringsmellanprogram, se ordning för Vidarebefordrade rubriker-mellanprogram.
Förgrena pipelinen för mellanprogram
Map tillägg används som en konvention för att förgrena pipelinen.
Map
förgrenar pipelinen för begäran baserat på matchningar av den angivna sökvägen för begäran. Om sökvägen för begäran börjar med den angivna sökvägen körs grenen.
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");
});
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod.
Begäran | Svar |
---|---|
localhost:1234 | Hej från ombud som inte är mappade. |
localhost:1234/map1 | Karttest 1 |
localhost:1234/map2 | Karttest 2 |
localhost:1234/map3 | Hej från en icke-Map-delegat. |
När Map
används tas de matchade sökvägssegmenten bort från HttpRequest.Path
och läggs till i HttpRequest.PathBase
för varje begäran.
Map
stöder kapsling, till exempel:
app.Map("/level1", level1App => {
level1App.Map("/level2a", level2AApp => {
// "/level1/level2a" processing
});
level1App.Map("/level2b", level2BApp => {
// "/level1/level2b" processing
});
});
Map
kan också matcha flera segment samtidigt:
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 förgrenar pipelinen för begäran baserat på resultatet av det angivna predikatet. Alla predikat av typen Func<HttpContext, bool>
kan användas för att mappa begäranden till en ny gren av pipelinen. I följande exempel används ett predikat för att identifiera förekomsten av en frågesträngsvariabel 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}");
});
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod:
Begäran | Svar |
---|---|
localhost:1234 |
Hello from non-Map delegate. |
localhost:1234/?branch=main |
Branch used = main |
UseWhen förgrenar även pipelinen för begäran baserat på resultatet av det angivna predikatet. Till skillnad från med MapWhen
återansluts den här grenen till huvudpipelinen om den inte kortsluter eller innehåller ett terminalmellanprogram:
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.
});
}
I föregående exempel skrivs ett svar av Hello from non-Map delegate.
för alla begäranden. Om begäran innehåller en frågesträngsvariabel branch
loggas dess värde innan huvudpipelinen återansluts.
Inbyggda mellanprogram
ASP.NET Core levereras med följande mellanprogramkomponenter. Kolumnen Order innehåller anteckningar om mellanprogramsplacering i pipelinen för bearbetning av begäranden och under vilka villkor mellanprogrammet kan avsluta bearbetningen av begäranden. När ett mellanprogram kortsluter pipelinen för bearbetning av begäranden och hindrar ytterligare underordnade mellanprogram från att bearbeta en begäran kallas det för en terminalmellanprogram. Mer information om kortslutning finns i avsnittet Skapa en pipeline för mellanprogram med WebApplication.
Mellanliggande programvara | Beskrivning | Beställning |
---|---|---|
autentisering | Tillhandahåller autentiseringsstöd. | Innan HttpContext.User behövs. Terminal för återanrop till OAuth. |
auktorisering | Tillhandahåller auktoriseringsstöd. | Omedelbart efter autentiseringsmellanprogrammet. |
Cookie policy | Spårar medgivande från användare för lagring av personlig information och tillämpar minimistandarder för cookie fält, till exempel secure och SameSite . |
Före mellanprogram som utfärdar webbkakor. Exempel: Autentisering, Session, MVC (TempData). |
CORS | Konfigurerar resursdelning mellan ursprung. | Före komponenter som använder CORS.
UseCors måste för närvarande komma före UseResponseCaching på grund av detta fel. |
DeveloperExceptionPage | Genererar en sida med felinformation som endast är avsedd att användas i utvecklingsmiljön. | Före komponenter som genererar fel. Projektmallarna registrerar automatiskt den här middlewarekomponenten som den första i pipelinen när miljön är Utvecklingsmiljö. |
Diagnostik | Flera separata mellanprogram som tillhandahåller en undantagssida för utvecklare, undantagshantering, statuskodsidor och standardwebbsidan för nya appar. | Före komponenter som genererar fel. Terminal för undantag eller servering av standardwebbsidan för nya appar. |
vidarebefordrade rubriker | Vidarebefordrar proxierade huvuden till den aktuella begäran. | Före komponenter som använder de uppdaterade fälten. Exempel: schema, värd, klient-IP, metod. |
hälsokontroll | Kontrollerar hälsotillståndet för en ASP.NET Core-app och dess beroenden, till exempel att kontrollera databasens tillgänglighet. | Terminal om en begäran matchar en slutpunkt för hälsokontroll. |
Rubrikpropagering | Sprider HTTP-huvuden från den inkommande begäran till utgående HTTP-klientbegäranden. | |
HTTP-loggning | Loggar HTTP-begäranden och svar. | I början av pipelinen för mellanprogram. |
Åsidosättning av HTTP-metod | Tillåter att en inkommande POST-begäran åsidosätter metoden. | Före komponenter som använder den uppdaterade metoden. |
HTTPS-omdirigering | Omdirigera alla HTTP-begäranden till HTTPS. | Före komponenter som använder URL:en. |
HTTP Strict Transport Security (HSTS) | Mellanprogram för säkerhetsförbättringar som lägger till ett särskilt svarshuvud. | Innan svar skickas och efter komponenter som ändrar begäranden. Exempel: Vidarebefordrade rubriker, URL-omskrivning. |
MVC - | Bearbetar begäranden med MVC/Razor Pages. | Terminal om en begäran matchar en rutt. |
OWIN | Interop med OWIN-baserade appar, servrar och mellanprogramvara. | Terminal om OWIN Middleware fullständigt bearbetar begäran. |
cachelagring av utdata | Ger stöd för cachelagringssvar baserat på konfiguration. | Före komponenter som kräver cachelagring.
UseRouting måste komma före UseOutputCaching .
UseCORS måste komma före UseOutputCaching . |
cachelagring av svar | Ger stöd för cachelagring av svar. Detta kräver att klienten deltar i arbetet. Använd cachelagring av utdata för fullständig serverkontroll. | Före komponenter som kräver cachelagring.
UseCORS måste komma före UseResponseCaching . Är vanligtvis inte fördelaktigt för användargränssnittsappar som Razor Pages eftersom webbläsare vanligtvis anger begärandehuvuden som förhindrar cachelagring.
Cachelagring av utdata gynnar användargränssnittsappar. |
Begär dekomprimering | Ger stöd för dekomprimering av begäranden. | Före komponenter som läser begärandetexten. |
komprimering av svar | Ger stöd för att komprimera svar. | Före komponenter som kräver komprimering. |
Begär lokaliseringsrutin | Tillhandahåller lokaliseringsstöd. | Före lokalisering av känsliga komponenter. Måste visas efter routning av mellanprogram när du använder RouteDataRequestCultureProvider. |
Slutpunktsroutning | Definierar och begränsar begärandevägar. | Terminal för matchande rutter. |
SPA | Hanterar alla begäranden från den här punkten i mellanprogramskedjan genom att returnera standardsidan för spa-programmet (Single Page Application) | Sent i kedjan, så att andra mellanprogram för att hantera statiska filer, MVC-åtgärder osv. har företräde. |
session | Ger stöd för hantering av användarsessioner. | Före komponenter som kräver session. |
Statiska filer | Ger stöd för att hantera statiska filer och katalogbläddring. | Terminal om en begäran matchar en fil. |
URL Omskrivning | Ger stöd för att skriva om URL:er och omdirigera begäranden. | Före komponenter som använder URL:en. |
W3CLogging | Genererar serveråtkomstloggar i W3C Extended Log File Format. | I början av pipelinen för mellanprogram. |
WebSockets | Aktiverar WebSockets-protokollet. | Innan komponenter som krävs för att kunna acceptera WebSocket-begäranden. |
Ytterligare resurser
- Alternativ för livslängd och registrering innehåller ett fullständigt exempel på mellanprogram med begränsade, tillfälligaoch singleton- livslängdstjänster.
- Skriva anpassade ASP.NET Core-mellanprogram
- Testa ASP.NET Core-mellanprogram
- Konfigurera gRPC-Web i ASP.NET Core
- Migrera HTTP-hanterare och -moduler till ASP.NET Core-mellanprogram
- Applikationsstart i ASP.NET Core
- begär funktioner i ASP.NET Core
- Fabriksbaserad aktivering av mellanprogram i ASP.NET Core
- Mellanprogramsaktivering med en tredjepartscontainer i ASP.NET Core
Av Rick Anderson och Steve Smith
Mellanprogram är programvara som monteras i en apppipeline för att hantera begäranden och svar. Varje komponent:
- Väljer om begäran ska skickas till nästa komponent i pipelinen.
- Kan utföra arbete före och efter nästa komponent i pipelinen.
Begärandedelegater används för att skapa pipelinen för begäran. Begärandedelegaterna hanterar varje HTTP-begäran.
Begärandeombud konfigureras med hjälp av Run, Mapoch Use utökningar. En delegeringsrepresentant för enskilda begäranden kan anges inline som en anonym metod (kallas inline-middleware) eller definieras i en återanvändbar klass. Dessa återanvändbara klasser och in-line anonyma metoder är middleware, även kända som middlewarekomponenter. Varje mellanprogramskomponent i begärandepipelinen ansvarar för att anropa nästa komponent i pipelinen eller kortsluta pipelinen. När ett mellanprogram kortsluts kallas det för ett terminalmellanprogram eftersom det förhindrar att ytterligare mellanprogram bearbetar begäran.
Migrera HTTP-hanterare och moduler till ASP.NET Core-mellanprogram förklarar skillnaden mellan pipelines för begäran i ASP.NET Core och ASP.NET 4.x och innehåller ytterligare mellanprogramsexempel.
Kodanalys för mellanprogram
ASP.NET Core innehåller många analysverktyg för kompilatorns plattform som kontrollerar programkoden för kvalitet. Mer information finns i Code-analys i ASP.NET Core-appar
Skapa en pipeline för mellanprogram med WebApplication
ASP.NET Core pipeline för begäran består av en sekvens med begärande-delegater som anropas i följd. Följande diagram visar konceptet. Utförandetråden följer de svarta pilarna.
Varje ombud kan utföra åtgärder före och efter nästa ombud. Ombud för undantagshantering bör anropas tidigt i pipelinen, så att de kan fånga upp undantag som inträffar i senare skeden av pipelinen.
Den enklaste möjliga ASP.NET Core-appen konfigurerar ett ombud för en enda begäran som hanterar alla begäranden. Det här fallet innehåller inte en pipeline för faktiska begäranden. I stället anropas en enda anonym funktion som svar på varje HTTP-begäran.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
app.Run();
Kedja flera begärandeombud tillsammans med Use. Parametern next
representerar nästa ombud i pipelinen. Du kan kortsluta pipelinen genom att inte anropa parametern next
. Du kan vanligtvis utföra åtgärder både före och efter next
ombud, vilket visas i följande exempel:
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();
När en delegat inte skickar en begäran till nästa delegat kallas det kortslutning av begäransrörledningen. Kortslutning är ofta önskvärt eftersom det undviker onödigt arbete. Till exempel kan Static File Middleware fungera som ett terminalmellanprogram genom att bearbeta en begäran om en statisk fil och kortsluta pipelinens rest. Mellanprogram som lagts till i pipelinen innan mellanprogrammet som avslutar ytterligare bearbetning bearbetar fortfarande kod efter deras next.Invoke
-instruktioner. Se dock följande varning om att försöka skriva till ett svar som redan har skickats.
Varning
Anropa inte next.Invoke
när svaret har skickats till klienten. Ändringar i HttpResponse efter att svaret har påbörjats kastar ett undantag. Till exempel inställningshuvuden och en statuskod utlöser ett undantag. Skriva till svarstexten efter anrop av next
:
- Kan orsaka en protokollöverträdelse. Du kan till exempel skriva mer än den angivna
Content-Length
. - Kan skada formateringen av kroppen. Du kan till exempel skriva en HTML-sidfot till en CSS-fil.
HasStarted är ett användbart tips för att ange om rubriker har skickats eller om brödtexten har skrivits till.
Run delegerade får ingen next
parameter. Den första Run
-delegaten är alltid terminal och terminerar pipelinen.
Run
är en konvention. Vissa mellanprogramskomponenter kan exponera Run[Middleware]
metoder som körs i slutet av pipelinen:
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();
Om du vill se kodkommentar översatta till andra språk än engelska kan du meddela oss i det här GitHub-diskussionsproblemet.
I föregående exempel skriver Run
-ombudet "Hello from 2nd delegate."
till svaret och avslutar sedan pipelinen. Om ett annat Use
- eller Run
-ombud läggs till efter Run
-ombudet, kommer det inte att anropas.
Föredrar app. Använd överlagring som kräver att kontexten skickas till nästa
Den appen som inte allokeras. Använd tilläggsmetod:
- Kräver att kontexten skickas till
next
. - Sparar två interna allokeringar per begäran som krävs när du använder den andra överlagringen.
Mer information finns i det här GitHub-ärendet.
Mellanprogramsordning
Följande diagram visar den fullständiga pipelinen för bearbetning av begäranden för ASP.NET Core MVC- och Razor Pages-appar. Du kan se hur befintliga mellanprogram sorteras i en typisk app och var anpassade mellanprogram läggs till. Du har fullständig kontroll över hur du ändrar ordning på befintliga mellanprogram eller matar in nya anpassade mellanprogram efter behov för dina scenarier.
Endpoint-mellanprogrammet i föregående diagram kör filterpipelinen för MVC eller Razor Pages.
Routing mellanprogrammet i föregående diagram visas efter statiska filer. Det här är den ordning som projektmallarna implementerar genom att uttryckligen anropa app. UseRouting. Om du inte anropar app.UseRouting
körs Routning mellanprogram i början av pipelinen som standard. Mer information finns i Routning.
Ordningen som mellanprogramkomponenter läggs till i filen Program.cs
definierar i vilken ordning mellanprogramkomponenterna anropas på begäranden och omvänd ordning för svaret. Ordningen är kritisk för säkerhet, prestanda och funktioner.
Följande markerade kod i Program.cs
lägger till säkerhetsrelaterade mellanprogramskomponenter i den vanliga rekommenderade ordningen:
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();
I föregående kod:
- Mellanprogram som inte läggs till när du skapar en ny webbapp med enskilda användarkonton kommenteras ut.
- Inte alla mellanprogram visas i den här exakta ordningen, men många gör det. Till exempel:
-
UseCors
,UseAuthentication
ochUseAuthorization
måste visas i den ordning som visas. -
UseCors
måste för närvarande visas innanUseResponseCaching
. Det här kravet förklaras i GitHub-ärende dotnet/aspnetcore #23218. -
UseRequestLocalization
måste visas före alla mellanprogram som kan kontrollera begärandekulturen (till exempelapp.UseMvcWithDefaultRoute()
).
-
I vissa scenarier har mellanprogram olika sortering. Cachelagring och komprimeringsordning är till exempel scenariospecifika och det finns flera giltiga ordningar. Till exempel:
app.UseResponseCaching();
app.UseResponseCompression();
Med föregående kod kan cpu-användningen minskas genom cachelagring av det komprimerade svaret, men du kan komma att cachelagra flera representationer av en resurs med hjälp av olika komprimeringsalgoritmer som Gzip eller Brotli.
Följande ordning kombinerar statiska filer för att tillåta cachelagring av komprimerade statiska filer:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();
Följande Program.cs
kod lägger till mellanprogramskomponenter för vanliga appscenarier:
- Undantags-/felhantering
- När appen körs i utvecklingsmiljön:
- Developer Exception Page Middleware (UseDeveloperExceptionPage) rapporterar appkörningsfel.
- Database Error Page Middleware (UseDatabaseErrorPage) rapporterar databaskörningsfel.
- När appen körs i produktionsmiljön:
- Undantagshanterarens mellanprogram (UseExceptionHandler) fångar undantag som genereras i följande mellanprogram.
- HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) lägger till
Strict-Transport-Security
-huvudet.
- När appen körs i utvecklingsmiljön:
- HTTPS Redirection Middleware (UseHttpsRedirection) omdirigerar HTTP-begäranden till HTTPS.
- Static File Middleware (UseStaticFiles) returnerar statiska filer och bryter av vidare bearbetning av begäranden.
- Cookie Policy Middleware (UseCookiePolicy) överensstämmer med eu:s allmänna dataskyddsförordning (GDPR).
- Routning av mellanprogram (UseRouting) för att dirigera begäranden.
- Autentisering mellanprogram (UseAuthentication) försöker autentisera användaren innan de får åtkomst till säkra resurser.
- Authorization Middleware (UseAuthorization) ger en användare åtkomst till säkra resurser.
- Sessionsmellanprogram (UseSession) upprättar och underhåller sessionstillstånd. Om appen använder sessionstillstånd anropar du Sessionsmellanprogrammet efter Cookie Policy-mellanprogram och före MVC-mellanprogram.
- Slutpunktsdirigering mellanprogram (UseEndpoints med MapRazorPages) för att lägga till Razor Pages-slutpunkter i begärandepipelinen.
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();
I föregående exempelkod exponeras varje mellanprogramstilläggsmetod på WebApplicationBuilder genom Microsoft.AspNetCore.Builder namnrymd.
UseExceptionHandler är den första mellanprogramskomponenten som läggs till i pipelinen. Därför fångar undantagshanterarens mellanprogram alla undantag som inträffar i senare anrop.
Static File Middleware anropas tidigt i pipelinen så att den kan hantera begäranden och kortslutning utan att gå igenom de återstående komponenterna. Mellanprogrammet för statiska filer ger inga auktoriseringskontroller. Alla filer som hanteras av Static File Middleware, inklusive de under wwwroot, är offentligt tillgängliga. En metod för att skydda statiska filer finns i Statiska filer i ASP.NET Core.
Om begäran inte hanteras av den statiska filmellanprogrammet skickas den vidare till autentiseringsmellanprogrammet (UseAuthentication), som utför autentisering. Autentisering kortsluter inte oautentiserade begäranden. Även om autentiseringsmiddleware autentiserar begäranden sker auktorisering (och avvisande) bara efter att MVC har valt en specifik Razor-sida eller MVC-kontroller och åtgärd.
I följande exempel visas en mellanprogramsordning där begäranden om statiska filer hanteras av Static File Middleware före Mellanprogram för svarskomprimering. Statiska filer komprimeras inte med den här mellanprogramsordningen. Svaren på Razor Pages kan komprimeras.
// Static files aren't compressed by Static File Middleware.
app.UseStaticFiles();
app.UseRouting();
app.UseResponseCompression();
app.MapRazorPages();
Information om ensidesprogram finns i guiderna för projektmallarna React och Angular.
UseCors- och UseStaticFiles-ordning
Ordningen för att anropa UseCors
och UseStaticFiles
beror på appen. Mer information finns i UseCors- och UseStaticFiles-order
Mellanprogramsordning för vidarebefordrade rubriker
Mellanprogram för vidarebefordrade rubriker ska köras före andra mellanprogram. Den här ordningen säkerställer att mellanprogrammet som förlitar sig på vidarebefordrad rubrikinformation kan använda huvudvärdena för bearbetning. Information om hur du kör vidarebefordrade huvudmellanprogram efter diagnostik och felhantering av mellanprogram finns i Vidarebefordrade rubriker mellanprogramsordning.
Förgrena mellanprogramspipelinen
Map-förlängningar används som en konvention för att fördela pipelinen.
Map
förgrenar pipelinen för begäran baserat på matchningar av den angivna sökvägen för begäran. Om sökvägen för begäran börjar med den angivna sökvägen körs grenen.
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");
});
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod.
Begäran | Svar |
---|---|
localhost:1234 | Hej från ombud som inte är mappade. |
localhost:1234/map1 | Karttest 1 |
localhost:1234/map2 | Karttest 2 |
localhost:1234/map3 | Hej från en icke-Map-delegat. |
När Map
används tas de matchade sökvägssegmenten bort från HttpRequest.Path
och läggs till i HttpRequest.PathBase
för varje begäran.
Map
stöder kapsling, till exempel:
app.Map("/level1", level1App => {
level1App.Map("/level2a", level2AApp => {
// "/level1/level2a" processing
});
level1App.Map("/level2b", level2BApp => {
// "/level1/level2b" processing
});
});
Map
kan också matcha flera segment samtidigt:
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 förgrenar pipelinen för begäran baserat på resultatet av det angivna predikatet. Alla predikat av typen Func<HttpContext, bool>
kan användas för att mappa begäranden till en ny gren av pipelinen. I följande exempel används ett predikat för att identifiera förekomsten av en frågesträngsvariabel 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}");
});
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod:
Begäran | Svar |
---|---|
localhost:1234 |
Hello from non-Map delegate. |
localhost:1234/?branch=main |
Branch used = main |
UseWhen förgrenar även pipelinen för begäran baserat på resultatet av det angivna predikatet. Till skillnad från med MapWhen
återansluts den här grenen till huvudpipelinen om den inte kortsluter eller innehåller ett terminalmellanprogram:
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.
});
}
I föregående exempel skrivs ett svar av Hello from non-Map delegate.
för alla begäranden. Om begäran innehåller en frågesträngsvariabel branch
loggas dess värde innan huvudpipelinen återansluts.
Inbyggda mellanprogram
ASP.NET Core levereras med följande mellanprogramkomponenter. Kolumnen Order innehåller anteckningar om mellanprogramsplacering i pipelinen för bearbetning av begäranden och under vilka villkor mellanprogrammet kan avsluta bearbetningen av begäranden. När ett mellanprogram kortsluter pipelinen för bearbetning av begäranden och hindrar ytterligare underordnade mellanprogram från att bearbeta en begäran kallas det för en terminalmellanprogram. Mer information om kortslutning finns i avsnittet Skapa en pipeline för mellanprogram med WebApplication.
Mellanprogram | Beskrivning | Beställning |
---|---|---|
autentisering | Tillhandahåller autentiseringsstöd. | Innan HttpContext.User behövs. Terminal för återanrop till OAuth. |
Behörighet | Tillhandahåller auktoriseringsstöd. | Omedelbart efter autentiseringsmellanprogrammet. |
Cookie policy | Spårar medgivande från användare för lagring av personlig information och tillämpar minimistandarder för cookie fält, till exempel secure och SameSite . |
Före mellanprogram som utfärdar cookies. Exempel: Autentisering, Session, MVC (TempData). |
CORS | Konfigurerar resursdelning mellan ursprung. | Före komponenter som använder CORS.
UseCors måste för närvarande gå före UseResponseCaching på grund av den här buggen. |
DeveloperExceptionPage | Genererar en sida med felinformation som endast är avsedd att användas i utvecklingsmiljön. | Före komponenter som genererar fel. Projektmallarna registrerar automatiskt denna mellanprogramvara som den första i pipelinen när miljön är i utvecklingsläget. |
Diagnostik | Flera separata mellanprogram som tillhandahåller en undantagssida för utvecklare, undantagshantering, statuskodsidor och standardwebbsidan för nya appar. | Före komponenter som genererar fel. Terminal för undantag eller servering av standardwebbsidan för nya appar. |
vidarebefordrade rubriker | Vidarebefordrar proxierade headers till den aktuella begäran. | Före de komponenter som använder de uppdaterade fälten. Exempel: schema, värd, klient-IP, metod. |
hälsokontroll | Kontrollerar hälsotillståndet för en ASP.NET Core-app och dess beroenden, till exempel att kontrollera databasens tillgänglighet. | Terminal om en begäran matchar en slutpunkt för hälsokontroll. |
Huvudspridning | Sprider HTTP-huvuden från den inkommande begäran till utgående HTTP-klientbegäranden. | |
HTTP-loggning | Loggar HTTP-begäranden och svar. | I början av pipelinen för mellanprogram. |
åsidosättning av HTTP-metod | Tillåter att en inkommande POST-begäran åsidosätter metoden. | Före komponenter som använder den uppdaterade metoden. |
HTTPS-omdirigering | Omdirigera alla HTTP-begäranden till HTTPS. | Före komponenter som använder URL:en. |
HTTP Strict Transport Security (HSTS) | Mellanprogram för säkerhetsförbättringar som lägger till ett särskilt svarshuvud. | Innan svar skickas och efter komponenter som ändrar begäranden. Exempel: Vidarebefordrade rubriker, URL-omskrivning. |
MVC | Bearbetar begäranden med MVC/Razor Pages. | Terminal om en begäran matchar en rutt. |
OWIN | Interop med OWIN-baserade appar, servrar och mellanprogramvara. | Terminal om OWIN Middleware fullständigt bearbetar begäran. |
Begär dekomprimering | Ger stöd för dekomprimering av begäranden. | Före komponenter som läser begärandetexten. |
Cachelagring av svar | Tillhandahåller stöd för caching av svar. | Före komponenter som kräver cachelagring.
UseCORS måste komma före UseResponseCaching . |
komprimering av svar | Ger stöd för att komprimera svar. | Före komponenter som kräver komprimering. |
Förfrågan om lokalisering | Tillhandahåller lokaliseringsstöd. | Före lokalisering av känsliga komponenter. Måste visas efter routning av mellanprogram när du använder RouteDataRequestCultureProvider. |
Slutpunktsroutning | Definierar och begränsar begärandevägar. | Terminal för matchande rutter. |
SPA | Hanterar alla begäranden från den här punkten i mellanprogramskedjan genom att returnera standardsidan för spa-programmet (Single Page Application) | Sent i kedjan, så att andra mellanprogram för att hantera statiska filer, MVC-åtgärder osv. har företräde. |
Session | Ger stöd för hantering av användarsessioner. | Före komponenter som kräver sessionshantering. |
Statiska filer | Ger stöd för att hantera statiska filer och katalogbläddring. | Terminal om en begäran matchar en fil. |
URL Omskrivning | Ger stöd för att skriva om URL:er och omdirigera begäranden. | Före komponenter som använder URL:en. |
W3CLogging | Genererar serveråtkomstloggar i W3C Extended Log File Format. | I början av pipelinen för mellanprogram. |
WebSockets | Aktiverar WebSockets-protokollet. | Före de komponenter som krävs för att acceptera WebSocket-begäranden. |
Ytterligare resurser
- Alternativ för livslängd och registrering innehåller ett komplett exempel på middleware med scoped-, transient-och singleton- livslängdstjänster.
- Skriva anpassade ASP.NET Core-mellanprogram
- Testa ASP.NET Core-mellanprogram
- Konfigurera gRPC-Web i ASP.NET Core
- Migrera HTTP-hanterare och -moduler till ASP.NET Core-mellanprogram
- App-start i ASP.NET Core
- begär funktioner i ASP.NET Core
- Fabriksbaserad aktivering av mellanprogram i ASP.NET Core
- Mellanprogramsaktivering med en tredjepartscontainer i ASP.NET Core
Av Rick Anderson och Steve Smith
Mellanprogram är programvara som monteras i en apppipeline för att hantera begäranden och svar. Varje komponent:
- Väljer om begäran ska skickas till nästa komponent i pipelinen.
- Kan utföra arbete före och efter nästa komponent i pipelinen.
Begärandedelegater används för att skapa pipelinen för begäran. Begärandedelegaterna hanterar varje HTTP-begäran.
Begäran-delegater konfigureras med Run, Mapoch Use tilläggsmetoder. Ett ombud för enskilda begäranden kan anges in-line som en anonym metod (kallas in-line middleware) eller definieras i en återanvändbar klass. Dessa återanvändbara klasser och in-line anonyma metoder är mellanprogram, kallas även mellanprogramskomponenter. Varje mellanprogramskomponent i begärandepipelinen ansvarar för att anropa nästa komponent i pipelinen eller kortsluta pipelinen. När ett mellanprogram kortsluts kallas det för ett terminalmellanprogram eftersom det förhindrar att ytterligare mellanprogram bearbetar begäran.
Migrera HTTP-hanterare och moduler till ASP.NET Core-mellanprogram förklarar skillnaden mellan pipelines för begäran i ASP.NET Core och ASP.NET 4.x och innehåller ytterligare mellanprogramsexempel.
Skapa en pipeline för mellanprogram med IApplicationBuilder
Pipelinen för ASP.NET Core-begäran består av en sekvens med begärandedelegater som anropas i tur och ordning. Följande diagram visar konceptet. Körningstråden följer de svarta pilarna.
Varje ombud kan utföra åtgärder före och efter nästa ombud. Ombud för undantagshantering bör anropas tidigt i pipelinen, så att de kan fånga upp undantag som inträffar i senare skeden av pipelinen.
Den enklaste möjliga ASP.NET Core-appen konfigurerar ett ombud för en enda begäran som hanterar alla begäranden. Det här fallet innehåller inte en faktisk begärandepipeline. I stället anropas en enda anonym funktion som svar på varje HTTP-begäran.
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
}
}
Länka flera begärandeombud tillsammans med Use. Parametern next
representerar nästa ombud i pipelinen. Du kan kortsluta pipelinen genom att inte anropa parametern nästa. Du kan vanligtvis utföra åtgärder både före och efter nästa ombud, vilket visas i följande exempel:
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.");
});
}
}
När ett ombud inte skickar en begäran till nästa ombud kallas det kortsluta begärandepipelinen. Kortslutning är ofta önskvärt eftersom det undviker onödigt arbete. Till exempel kan Static File Middleware fungera som ett terminalmellanprogram genom att bearbeta en begäran om en statisk fil och kortsluta pipelinens rest. Mellanprogram som lagts till i pipelinen innan mellanprogrammet som avslutar ytterligare bearbetning bearbetar fortfarande kod efter deras next.Invoke
-instruktioner. Se dock följande varning om att försöka skriva till ett svar som redan har skickats.
Varning
Anropa inte next.Invoke
när svaret har skickats till klienten. Ändringar i HttpResponse när svaret har börjat generera ett undantag. Till exempel inställningshuvuden och en statuskod utlöser ett undantag. Skriva till svarstexten efter att ha anropat next
:
- Kan orsaka en protokollöverträdelse. Du kan till exempel skriva mer än den angivna
Content-Length
. - Kan skada brödtextformatet. Du kan till exempel skriva en HTML-sidfot till en CSS-fil.
HasStarted är ett användbart tips för att ange om rubriker har skickats eller om brödtexten har skrivits till.
Run ombud får ingen next
parameter. Den första Run
-delegaten är alltid slutlig och avslutar pipelinen.
Run
är en konvention. Vissa mellanprogramskomponenter kan exponera Run[Middleware]
metoder som körs i slutet av pipelinen:
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.");
});
}
}
Om du vill se kodkommentar översatta till andra språk än engelska kan du meddela oss i det här GitHub-diskussionsproblemet.
I föregående exempel skriver Run
-ombudet "Hello from 2nd delegate."
till svaret och avslutar sedan pipelinen. Om en annan Use
eller Run
ombud läggs till efter Run
ombud anropas den inte.
Mellanprogramsordning
Följande diagram visar den fullständiga pipelinen för bearbetning av begäranden för ASP.NET Core MVC- och Razor Pages-appar. Du kan se hur befintliga mellanprogram sorteras i en typisk app och var anpassade mellanprogram läggs till. Du har fullständig kontroll över hur du ändrar ordning på befintliga mellanprogram eller matar in nya anpassade mellanprogram efter behov för dina scenarier.
Endpoint mellanprogrammet i det föregående diagrammet exekverar filtreringspipeline för motsvarande applikationstyp – MVC eller Razor-sidor.
Ordningen som mellanprogramkomponenter läggs till i metoden Startup.Configure
definierar i vilken ordning mellanprogramkomponenterna anropas på begäranden och omvänd ordning för svaret. Ordningen är kritisk för säkerhet, prestanda och funktioner.
Följande Startup.Configure
-metod lägger till säkerhetsrelaterade mellanprogramskomponenter i den vanliga rekommenderade ordningen:
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?}");
});
}
I föregående kod:
- Mellanprogram som inte läggs till när du skapar en ny webbapp med enskilda användarkonton kommenteras ut.
- Inte alla mellanprogram visas i den här exakta ordningen, men många gör det. Till exempel:
-
UseCors
,UseAuthentication
ochUseAuthorization
måste visas i den ordning som visas. -
UseCors
måste för närvarande visas innanUseResponseCaching
på grund av detta fel . -
UseRequestLocalization
måste visas före alla mellanprogram som kan kontrollera begärandekulturen (till exempelapp.UseMvcWithDefaultRoute()
).
-
I vissa scenarier har mellanprogram olika sortering. Cachelagring och komprimeringsordning är till exempel scenariospecifika och det finns flera giltiga ordningar. Till exempel:
app.UseResponseCaching();
app.UseResponseCompression();
Med föregående kod kan CPU sparas genom att cachelagra det komprimerade svaret, men det kan sluta med att du cachelagrar flera representationer av en resurs med olika komprimeringsalgoritmer som Gzip eller Brotli.
Följande ordning kombinerar statiska filer för att tillåta cachelagring av komprimerade statiska filer:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();
Följande Startup.Configure
-metod lägger till mellanprogramskomponenter för vanliga appscenarier:
- Undantags-/felhantering
- När appen körs i utvecklingsmiljön:
- Developer Exception Page Middleware (UseDeveloperExceptionPage) rapporterar appkörningsfel.
- Databasfel Page Middleware rapporterar databaskörningsfel.
- När appen körs i produktionsmiljön:
- Undantagshanterarens mellanprogram (UseExceptionHandler) fångar undantag som genereras i följande mellanprogram.
- HTTP Strict Transport Security Protocol (HSTS) Middleware (UseHsts) lägger till
Strict-Transport-Security
-huvudet.
- När appen körs i utvecklingsmiljön:
- HTTPS Redirection Middleware (UseHttpsRedirection) omdirigerar HTTP-begäranden till HTTPS.
- Static File Middleware (UseStaticFiles) returnerar statiska filer och förhindrar ytterligare bearbetning av begäranden.
- Cookie Policy Middleware (UseCookiePolicy) överensstämmer med eu:s allmänna dataskyddsförordning (GDPR).
- Routning av mellanprogram (UseRouting) för att dirigera begäranden.
- Autentisering mellanprogram (UseAuthentication) försöker autentisera användaren innan de får åtkomst till säkra resurser.
- Authorization Middleware (UseAuthorization) ger en användare åtkomst till säkra resurser.
- Sessionsmellanprogram (UseSession) upprättar och underhåller sessionstillstånd. Om appen använder sessionstillstånd anropar du Sessionsmellanprogram efter Cookie principmellanprogram och före MVC Middleware.
- Mellanprogram för dirigering av slutpunkter (UseEndpoints med MapRazorPages) för att lägga till Razor Pages-slutpunkter i begäranspipeline.
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();
});
}
I föregående exempelkod exponeras varje mellanprogramstilläggsmetod på IApplicationBuilder via Microsoft.AspNetCore.Builder namnrymd.
UseExceptionHandler är den första mellanprogramskomponenten som läggs till i pipelinen. Därför fångar undantagshanterarens mellanprogram alla undantag som inträffar i senare anrop.
Static File Middleware anropas tidigt i pipelinen så att den kan hantera begäranden och kortslutning utan att gå igenom de återstående komponenterna. Mellanprogrammet för statiska filer ger inga auktoriseringskontroller. Alla filer som hanteras av Static File Middleware, inklusive de under wwwroot, är offentligt tillgängliga. En metod för att skydda statiska filer finns i Statiska filer i ASP.NET Core.
Om begäran inte hanteras av den statiska filmellanprogrammet skickas den vidare till autentiseringsmellanprogrammet (UseAuthentication), som utför autentisering. Autentisering kortsluter inte oautentiserade begäranden. Även om autentiseringsmiddleware autentiserar begäranden sker auktorisering (och avvisande) först efter att MVC har valt en specifik Razor-sida eller MVC-kontroller och åtgärd.
I följande exempel visas en mellanprogramsordning där begäranden om statiska filer hanteras av Static File Middleware före Mellanprogram för svarskomprimering. Statiska filer komprimeras inte med den här mellanprogramsordningen. Det går att komprimera svar från Razor-sidor.
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();
});
}
För ensidesprogram (SPA) kommer SPA-mellanprogrammet UseSpaStaticFiles vanligtvis sist i pipelinen för mellanprogram. SPA-mellanprogrammet kommer sist:
- För att tillåta att alla andra mellanprogram svarar på matchande begäranden först.
- För att tillåta att SPA:er med routning på klientsidan körs för alla vägar som inte är betrodda av serverappen.
Mer information om SPA finns i guiderna för projektmallarna React och Angular.
Mellanprogramsordning för vidarebefordrade rubriker
Mellanprogram för vidarebefordrade headers ska köras före andra mellanprogram. Den här ordningen säkerställer att mellanprogrammet som förlitar sig på vidarebefordrad rubrikinformation kan använda huvudvärdena för bearbetning. Information om hur du kör vidarebefordrade rubrikers mellanprogram efter mellanprogram för diagnostik och felhantering finns i Vidarebefordrade rubrikers mellanprogramsordning.
Förgrena pipelinen för mellanprogram
Map-förlängningar används som en standard för att förgrena pipelinesystemet.
Map
förgrenar pipelinen för begäran baserat på matchningar av den angivna sökvägen för begäran. Om sökvägen för begäran börjar med den angivna sökvägen körs grenen.
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.");
});
}
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod.
Begäran | Svar |
---|---|
localhost:1234 | Hej från ombud som inte är mappade. |
localhost:1234/map1 | Karttest 1 |
localhost:1234/map2 | Karttest 2 |
localhost:1234/map3 | Hej från ombud som inte är Map. |
När Map
används tas de matchade sökvägssegmenten bort från HttpRequest.Path
och läggs till i HttpRequest.PathBase
för varje begäran.
Map
stöder nästling, till exempel:
app.Map("/level1", level1App => {
level1App.Map("/level2a", level2AApp => {
// "/level1/level2a" processing
});
level1App.Map("/level2b", level2BApp => {
// "/level1/level2b" processing
});
});
Map
kan också matcha flera segment samtidigt:
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 förgrenar pipelinen för begäran baserat på resultatet av det angivna predikatet. Alla predikat av typen Func<HttpContext, bool>
kan användas för att mappa begäranden till en ny gren av pipelinen. I följande exempel används ett predikat för att identifiera förekomsten av en frågesträngsvariabel 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.");
});
}
}
I följande tabell visas begäranden och svar från http://localhost:1234
med hjälp av föregående kod:
Begäran | Svar |
---|---|
localhost:1234 | Hej från en ombud som inte är en Map-delegat. |
localhost:1234/?branch=main | Gren som används = main |
UseWhen förgrenar även pipelinen för begäran baserat på resultatet av det angivna predikatet. Till skillnad från med MapWhen
återansluts den här grenen till huvudpipelinen om den inte kortsluter eller innehåller ett terminalmellanprogram:
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.");
});
}
}
I det föregående exemplet skrivs svaret "Hej från huvudröret" för alla begäranden. Om begäran innehåller en frågesträngsvariabel branch
loggas dess värde innan huvudpipelinen återansluts.
Inbyggda mellanprogram
ASP.NET Core levereras med följande mellanprogramkomponenter. Kolumnen Order innehåller anteckningar om mellanprogramsplacering i pipelinen för bearbetning av begäranden och under vilka villkor mellanprogrammet kan avsluta bearbetningen av begäranden. När ett mellanprogram kortsluter pipelinen för bearbetning av begäranden och hindrar ytterligare underordnade mellanprogram från att bearbeta en begäran kallas det för en terminalmellanprogram. Mer information om kortslutning finns i avsnittet Skapa en pipeline för mellanprogram med IApplicationBuilder.
Mellanprogram | Beskrivning | Beställning |
---|---|---|
autentisering | Tillhandahåller autentiseringsstöd. | Innan HttpContext.User behövs. Terminal för återanrop till OAuth. |
Behörighet | Tillhandahåller auktoriseringsstöd. | Omedelbart efter autentiseringsmellanprogrammet. |
Cookie Policy | Spårar medgivande från användare för lagring av personlig information och tillämpar minimistandarder för cookie fält, till exempel secure och SameSite . |
Före mellanmjukvara som utfärdar cookies. Exempel: Autentisering, Session, MVC (TempData). |
CORS | Konfigurerar resursdelning mellan ursprung. | Före komponenter som använder CORS.
UseCors måste för närvarande gå före UseResponseCaching på grund av denna buggen. |
Diagnostik | Flera separata mellanprogram som tillhandahåller en undantagssida för utvecklare, undantagshantering, statuskodsidor och standardwebbsidan för nya appar. | Före komponenter som genererar fel. Terminal för undantag eller visning av standardwebbsidan för nya appar. |
vidarebefordrade rubriker | Vidarebefordrar proxierade headers till den aktuella begäran. | Före komponenter som använder de uppdaterade fälten. Exempel: schema, värd, klient-IP, metod. |
hälsokontroll | Kontrollerar hälsotillståndet för en ASP.NET Core-app och dess beroenden, till exempel att kontrollera databasens tillgänglighet. | Terminal om en begäran matchar en slutpunkt för hälsokontroll. |
Header-propagation | Sprider HTTP-huvuden från den inkommande begäran till utgående HTTP-klientbegäranden. | |
HTTP-metodöverskrivning | Tillåter att en inkommande POST-begäran åsidosätter metoden. | Före komponenter som använder den uppdaterade metoden. |
HTTPS-omdirigering | Omdirigera alla HTTP-begäranden till HTTPS. | Före komponenter som använder URL:en. |
HTTP Strict Transport Security (HSTS) | Mellanprogramvara för säkerhetsförbättringar som lägger till en särskild svarsrubrik. | Innan svar skickas och efter komponenter som ändrar begäranden. Exempel: Vidarebefordrade rubriker, URL-omskrivning. |
MVC | Bearbetar begäranden med MVC/Razor Pages. | Terminal om en begäran matchar en rutt. |
OWIN- | Interop med OWIN-baserade appar, servrar och mellanprogram. | Terminal om OWIN Middleware fullständigt bearbetar begäran. |
Svarscachning | Ger stöd för cachelagringssvar. | Före komponenter som kräver cachelagring.
UseCORS måste komma före UseResponseCaching . |
komprimering av svar | Ger stöd för att komprimera svar. | Före komponenter som kräver komprimering. |
Begär lokalisering | Tillhandahåller lokaliseringsstöd. | Före lokalisering av känsliga komponenter. Måste visas efter routning av mellanprogram när du använder RouteDataRequestCultureProvider. |
Slutpunktsroutning | Definierar och begränsar begärandevägar. | Terminal för matchande rutter. |
SPA | Hanterar alla begäranden från den här punkten i mellanprogramskedjan genom att returnera standardsidan för spa-programmet (Single Page Application) | Sent i kedjan, så att andra mellanprogram för att hantera statiska filer, MVC-åtgärder osv. har företräde. |
Session | Ger stöd för hantering av användarsessioner. | Före komponenter som kräver Session. |
Statiska filer | Ger stöd för att hantera statiska filer och katalogbläddring. | Terminal om en begäran matchar en fil. |
URL Omskrivning | Ger stöd för att skriva om URL:er och omdirigera begäranden. | Före komponenter som använder URL:en. |
WebSockets | Aktiverar WebSocket-protokollet. | Innan de komponenter som krävs för att acceptera WebSocket-förfrågningar. |
Ytterligare resurser
- Alternativ för livslängd och registrering innehåller ett fullständigt exempel på mellanprogram med begränsade, tillfälligaoch singleton- livslängdstjänster.
- Skriva anpassade ASP.NET Core-mellanprogram
- Testa ASP.NET Core-mellanprogram
- Migrera HTTP-hanterare och -moduler till ASP.NET Core-mellanprogram
- App-startup inom ASP.NET Core
- begär funktioner i ASP.NET Core
- Fabriksbaserad aktivering av mellanprogram i ASP.NET Core
- Mellanprogramsaktivering med en tredjepartscontainer i ASP.NET Core
ASP.NET Core