Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
Middleware ist Software, die zu einer Anwendungspipeline zusammengesetzt wird, um Anforderungen und Antworten zu verarbeiten. Jede Middleware:
- Wählt aus, ob die Anforderung an die nächste Middleware in der Pipeline übergeben werden soll.
- Kann Arbeiten ausführen, bevor oder nachdem die nächste Middleware in der Pipeline aufgerufen wird.
Anforderungsdelegaten werden verwendet, um die Anforderungspipeline zu erstellen. Die Anforderungsdelegaten behandeln jede HTTP-Anforderung.
Konfigurieren Sie Anforderungsdelegaten mithilfe der Erweiterungsmethoden Run, Map und Use. Sie können einen einzelnen Anforderungsdelegat inline als anonyme Methode (als Inline-Middleware bezeichnet) angeben oder in einer wiederverwendbaren Klasse definieren. Diese inline anonymen Methoden oder wiederverwendbaren Klassen werden als Middleware - oder Middleware-Komponenten bezeichnet. Jede Middleware in der Anfragepipeline ist dafür verantwortlich, die nächste Middleware in der Pipeline aufzurufen oder die Pipeline kurzzuschließen. Wenn eine Middleware einen Kurzschluss verursacht, wird diese als Terminalmiddleware bezeichnet, da sie verhindert, dass weitere Middleware die Anforderung verarbeiten kann.
Weitere Informationen zum Unterschied zwischen Anforderungspipelines in ASP.NET Core und ASP.NET 4.x mit zusätzlichen Middlewarebeispielen finden Sie unter Migrieren von HTTP-Modulen zu ASP.NET Core Middleware.
Rolle von Middleware nach App-Typ
Serverseitige Blazor und Razor Seiten sowie MVC verarbeiten Browseranforderungen auf dem Server mit Middleware. Die Anleitungen in diesem Artikel gelten für diese Arten von Apps.
Unabhängige Blazor WebAssembly-Apps werden vollständig auf dem Client ausgeführt und verarbeiten keine Anforderungen mit einer Middleware-Pipeline. Die Anleitung in diesem Artikel gilt nicht für eigenständige Blazor WebAssembly-Apps.
Middleware-Codeanalyse
Weitere Informationen zu den Compilerplattformanalysatoren von ASP.NET Core, die App-Code auf Qualität prüfen, finden Sie unter Diagnose-Code Analysis in ASP.NET Core Apps.
Erstellen einer Middlewarepipeline mit WebApplication
Die ASP.NET Core-Anforderungspipeline besteht aus einer Sequenz von Anforderungsdelegaten, die nacheinander aufgerufen werden. Das Konzept wird im folgenden Diagramm veranschaulicht. Der Ausführungsthread folgt den schwarzen Pfeilen.
Jeder Delegat kann Vorgänge vor und nach dem nächsten Delegaten ausführen. Die Ausnahmebehandlungsdelegaten sollen früh in der Pipeline aufgerufen werden, sodass sie Ausnahmen abfangen können, die in späteren Stadien der Pipeline auftreten.
Hinweis
Um lokal mit den Codebeispielen in diesem Abschnitt zu experimentieren, erstellen Sie eine ASP.NET Core-App mit der ASP.NET Core Empty-Projektvorlage . Bei Verwendung der .NET CLI lautet web der Kurzname der Vorlage (dotnet new web).
Die einfachste ASP.NET Core-App ruft Run auf, um eine einzelne Terminal-Middleware als anonymen Funktions-Request-Delegaten einzurichten, der Anfragen ohne eine Anforderungspipeline verarbeitet.
Im folgenden Beispiel:
- Der Aufruf von RunExtensions.Run wird bei jeder Anforderung ausgeführt und schreibt "Hello world!" in die Antwort.
- Der Aufruf von WebApplication.Run am Ende des Codeblocks führt die App aus und blockiert den aufrufenden Thread bis zum Herunterfahren des Hosts.
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Run(async context =>
{
await context.Response.WriteAsync("Hello world!");
});
app.Run();
Antwort beim Zugriff auf die App in einem Browser unter der Start-URL:
Hello world!
Mit Use können Sie mehrere Anforderungsdelegaten miteinander verknüpfen. Der Parameter next steht für den nächsten Delegaten in der Pipeline. In der Regel können Sie Aktionen vor und nach dem next-Delegat ausführen.
Dies wird im folgenden Beispiel veranschaulicht:
- Zwei Use Aufrufe, die jeweils in die Konsole geschrieben werden:
- Wo Aufgaben ausgeführt werden können, kann die Antwort (
context.Response, HttpResponse) geschrieben werden. - Wo Aufgaben durchgeführt werden, die keine Daten an die Antwort senden, nachdem der Parameter
nextaufgerufen wurde.
- Wo Aufgaben ausgeführt werden können, kann die Antwort (
- Ein Terminal-Anforderungsdelegat mit einem Aufruf von RunExtensions.Run, das "Hello world!" in die Antwort schreibt.
- Ein letzter Use Aufruf, der nie ausgeführt wird, da er dem Run Terminalanforderungsdelegat folgt.
- Ein Aufruf von WebApplication.Run am Ende des Codeblocks, um die App auszuführen und den aufrufenden Thread bis zum Herunterfahren des Hosts zu blockieren.
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();
Im Konsolenfenster der App, wenn die App ausgeführt wird:
Aufgaben, die Daten in die Antwort schreiben können. (1)
Aufgaben, die Daten in die Antwort schreiben können. (2)
Aufgaben, die keine Daten in die Antwort schreiben. (2)
Aufgaben, die keine Daten in die Antwort schreiben. (1)
Die Kurzschaltung der Anforderungspipeline ist häufig wünschenswert, da unnötige Arbeit vermieden wird. So kann beispielsweise Middleware für statische Dateien als terminale Middleware fungieren, indem sie eine Anforderung für eine statische Datei verarbeitet und den Rest der Pipeline umgeht. Middleware, die vor der Terminal-Middleware in die Pipeline eingefügt wurde, verarbeitet den Code nach deren next.Invoke-Anweisungen weiterhin. Wenn Sie nicht beabsichtigen, next.Invoke aufzurufen, da Ihr Ziel darin besteht, die Pipeline zu beenden, verwenden Sie stattdessen einen Run Delegaten anstatt die Use Erweiterungsmethode aufzurufen.
Rufen Sie next.Invoke während oder nach dem Senden der Antwort an den Client nicht auf. Nachdem ein HttpResponse Vorgang gestartet wurde, führen Änderungen zu einer Ausnahme. Das Festlegen von Headern oder ein Antwortstatuscode löst beispielsweise eine Ausnahme aus, nachdem die Antwort gestartet wurde. Wenn Sie nach dem Aufruf von next in den Antworttext schreiben, kann dies zu Folgendem führen:
- Es wird eine Protokollverletzung verursacht. Es werden beispielsweise mehr Bytes in die Antwort geschrieben als in der zulässigen Inhaltslänge des Antwort-Headers spezifiziert ist (
Content-LengthHeaderwert). - Der Textkörper kann beschädigt werden; es wird z. B. eine HTML-Fußzeile in eine CSS-Datei geschrieben.
Um festzustellen, ob die Antwort gestartet wurde, überprüfen Sie den Wert von HasStarted.
Weitere Informationen finden Sie unter Kurzschluss der Middleware nach dem Routing.
Run-Delegat
Ein Run-Delegat erhält keinen next-Parameter. Der erste Run Delegat beendet immer die Pipeline.
Run ist ebenfalls eine Konvention, und manche Middleware kann Run-Methoden offenlegen, die am Ende der Pipeline ausgeführt werden.
Alle Use oder Run-Delegaten nach dem ersten Run-Delegaten werden nicht aufgerufen.
Verzweigen der Middleware-Pipeline
Map Erweiterungen werden als Konvention verwendet, um die Anforderungsverarbeitungspipeline zu verzweigen. Map brancht die Anforderungspipeline auf Grundlage von Übereinstimmungen des angegebenen Anforderungspfads. Wenn der Anfragepfad mit dem angegebenen Pfad beginnt, wird der Zweig ausgeführt.
Im folgenden Beispiel wird HandleMap1 für Anforderungen an /map1 aufgerufen, und HandleMap2 wird für Anforderungen an /map2 aufgerufen.
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 der folgenden Tabelle sind die Anforderungen und Antworten mit dem vorherigen Code aufgeführt.
| Anforderung | Antwort |
|---|---|
/ |
Hello from the non-Map delegate. |
/map1 |
Map 1 |
/map2 |
Map 2 |
/map3 |
Hello from the non-Map delegate. |
Bei Verwendung von Map werden die übereinstimmenden Pfadsegmente aus HttpRequest.Path entfernt und für jede Anforderung an HttpRequest.PathBase angehängt.
Map kann mehrere Segmente gleichzeitig abgleichen:
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 der folgenden Tabelle sind die Anforderungen und Antworten mit dem vorherigen Code aufgeführt.
| Anforderung | Antwort |
|---|---|
/ |
Hello from the non-Map delegate. |
/map1/segment1 |
Processing '/map1/segment1' |
Map unterstützt Nesting:
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 der folgenden Tabelle sind die Anforderungen und Antworten mit dem vorherigen Code aufgeführt.
| Anforderung | Antwort |
|---|---|
/ |
Hello from the non-Map delegate. |
/level1/level2a |
Processing '/level1/level2a' |
/level1/level2b |
Processing '/level1/level2b' |
MapWhen verzweigt die Anforderungspipeline basierend auf dem Ergebnis des angegebenen Prädikats. Jedes Prädikat vom Typ Func<HttpContext, bool> kann verwendet werden, um Anforderungen einem neuen Branch der Pipeline zuzuordnen. Im folgenden Beispiel wird ein Prädikat verwendet, um das Vorhandensein einer Abfragezeichenfolgenvariable namens "branch" zu erkennen:
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 der folgenden Tabelle sind die Anforderungen und Antworten mit dem vorherigen Code aufgeführt.
| Anforderung | Antwort |
|---|---|
/ |
Hello from the non-Map delegate. |
/?branch=main |
Branch used = 'main' |
UseWhen kann die Anforderungspipeline basierend auf dem Ergebnis des angegebenen Prädikats verzweigen. Anders als bei MapWhen wird dieser Branch wieder mit der Hauptpipeline verbunden, wenn er keine Terminal-Middleware enthält:
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.");
});
}
Im vorherigen Beispiel wird eine Antwort von "Hello from the non-Map delegate." für alle Anforderungen geschrieben. Wenn die Anforderung eine Abfragezeichenfolgenvariable namens "branch" enthält, wird der Wert protokolliert, bevor zur Hauptpipeline zurückgekehrt wird.
Erstellen einer Middlewarepipeline mit IApplicationBuilder
Die ASP.NET Core-Anforderungspipeline besteht aus einer Sequenz von Anforderungsdelegaten, die nacheinander aufgerufen werden. Das Konzept wird im folgenden Diagramm veranschaulicht. Der Ausführungsthread folgt den schwarzen Pfeilen.
Jeder Delegat kann Vorgänge vor und nach dem nächsten Delegaten ausführen. Die Ausnahmebehandlungsdelegaten sollen früh in der Pipeline aufgerufen werden, sodass sie Ausnahmen abfangen können, die in späteren Stadien der Pipeline auftreten.
Die einfachste mögliche ASP.NET Core-App enthält einen einzigen Anforderungsdelegaten, der alle Anforderungen verarbeitet. In diesem Fall ist keine tatsächliche Anforderungspipeline vorhanden. Stattdessen wird eine einzelne anonyme Funktion als Antwort auf jede HTTP-Anforderung aufgerufen.
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
}
}
Mit Use können Sie mehrere Anforderungsdelegaten miteinander verknüpfen. Der Parameter next steht für den nächsten Delegaten in der Pipeline. Sie können die Pipeline kurzschließen, indem Sie nicht den Parameter next aufrufen. Normalerweise können Sie Aktionen sowohl vor als auch nach dem nächsten Delegaten durchführen. Dies wird in folgendem Beispiel veranschaulicht:
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.
});
Wenn ein Delegierter eine Anforderung nicht an den nächsten Delegierten übergibt, wird dies als Kurzschluss der Anforderungspipeline bezeichnet. Das Kurzschließen ist oft sinnvoll, da es unnötige Arbeit verhindert. So kann beispielsweise Middleware für statische Dateien als terminale Middleware fungieren, indem sie eine Anforderung für eine statische Datei verarbeitet und den Rest der Pipeline umgeht. Middleware, die noch vor der Middleware, die die weitere Verarbeitung beendet, zur Pipeline hinzugefügt wird, verarbeitet Code noch nach den next.Invoke-Anweisungen weiter. Sehen Sie sich allerdings die folgende Warnung zum Versuch an, in eine Antwort zu schreiben, die bereits gesendet wurde.
Warnung
Rufen Sie next.Invoke nicht auf, nachdem die Antwort an den Client gesendet wurde. Änderungen an HttpResponse lösen nach dem Start der Antwort eine Ausnahme aus. Das Festlegen von Headern und einem Statuscode lösen beispielsweise eine Ausnahme aus. Wenn Sie nach dem Aufruf von next in den Antworttext schreiben, kann dies:
- einen Protokollverstoß verursachen, Zum Beispiel, mehr als das angegebene
Content-Lengthzu schreiben. - Fehler im Textformat auslösen, wenn Sie z.B. eine HTML-Fußzeile in eine CSS-Datei schreiben.
HasStarted ist ein nützlicher Hinweis, um anzuzeigen, ob Kopfzeilen gesendet wurden oder der Text geschrieben wurde.
Run-Delegaten erhalten keinen next-Parameter. Der erste Run-Delegat ist immer terminal und beendet die Pipeline.
Run ist eine Konvention. Einige Middlewarekomponenten machen möglicherweise Run[Middleware]-Methoden verfügbar, die am Ende einer Pipeline ausgeführt werden:
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd delegate.");
});
Im vorherigen Beispiel schreibt der Run-Delegat "Hello from 2nd delegate." zur Antwort und beendet dann die Pipeline. Wenn ein anderer Use- oder Run-Delegat nach dem Run-Delegaten hinzugefügt wird, wird dieser nicht aufgerufen.
Verzweigen der Middleware-Pipeline
Map Erweiterungen werden als Konvention für die Verzweigung der Pipeline verwendet.
Map brancht die Anforderungspipeline auf Grundlage von Übereinstimmungen des angegebenen Anforderungspfads. Wenn der Anfragepfad mit dem angegebenen Pfad beginnt, wird der Zweig ausgeführt.
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 der folgenden Tabelle sind die Anfragen und Antworten von http://localhost:1234 mit dem vorherigen Code aufgelistet.
| Anforderung | Antwort |
|---|---|
| localhost:1234 | Hello from non-Map delegate. |
| localhost:1234/map1 | Kartentest 1 |
| localhost:1234/map2 | Kartentest 2 |
| localhost:1234/map3 | Hello from non-Map delegate. |
Bei Verwendung von Map werden die übereinstimmenden Pfadsegmente aus HttpRequest.Path entfernt und für jede Anforderung an HttpRequest.PathBase angehängt.
Map unterstützt z. B. Verschachtelungen:
app.Map("/level1", level1App => {
level1App.Map("/level2a", level2AApp => {
// "/level1/level2a" processing
});
level1App.Map("/level2b", level2BApp => {
// "/level1/level2b" processing
});
});
Map kann auch mehrere Segmente auf einmal abgleichen:
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 verzweigt die Anforderungspipeline basierend auf dem Ergebnis des angegebenen Prädikats. Sie können jedes Prädikat des Typs Func<HttpContext, bool> verwenden, um Anforderungen einem neuen Zweig der Pipeline zuzuordnen. Im folgenden Beispiel erkennt ein Prädikat das Vorhandensein einer Abfragezeichenfolgenvariable 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 der folgenden Tabelle sind die Anfragen und Antworten von http://localhost:1234 mit dem vorherigen Code aufgelistet.
| Anforderung | Antwort |
|---|---|
| localhost:1234 | Hello from non-Map delegate. |
| localhost:1234/?branch=main | Branch used = main |
UseWhen verzweigt auch die Anforderungspipeline basierend auf dem Ergebnis des angegebenen Prädikats. Anders als bei MapWhen wird dieser Branch wieder mit der Hauptpipeline verbunden, wenn er nicht kurzgeschlossen wird oder eine Terminalmiddleware enthält:
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.");
});
}
}
Im vorherigen Beispiel wird die Antwort „Hello from main pipeline“ für alle Anforderungen ausgegeben. Wenn die Anforderung eine Abfragezeichenfolgevariable branch enthält, wird ihr Wert protokolliert, bevor die Hauptpipeline wiederhergestellt wird.
Middleware automatisch hinzugefügt von WebApplication
WebApplicationFügt die folgende Middleware automatisch in ASP.NET Core Apps hinzu, je nach bestimmten Bedingungen:
-
UseDeveloperExceptionPagewird zuerst hinzugefügt, wennHostingEnvironmentgleich"Development"ist. -
UseRoutingwird zweitens hinzugefügt, wenn der BenutzercodeUseRoutingnoch nicht aufgerufen hat, und wenn Endpunkte konfiguriert sind, z. B.app.MapGet. -
UseEndpointswird am Ende der Middleware-Pipeline hinzugefügt, wenn mindestens ein Endpunkt konfiguriert ist. -
UseAuthenticationwird unmittelbar nachUseRoutinghinzugefügt, wenn der BenutzercodeUseAuthenticationnoch nicht aufgerufen hat und wennIAuthenticationSchemeProviderim Dienstanbieter erkannt werden kann.IAuthenticationSchemeProviderwird standardmäßig hinzugefügt, wennAddAuthenticationverwendet wird, und Dienste werden mitIServiceProviderIsServiceerkannt. -
UseAuthorizationwird als Nächstes hinzugefügt, wenn der BenutzercodeUseAuthorizationnoch nicht aufgerufen hat und wennIAuthorizationHandlerProviderim Dienstanbieter erkannt werden kann.IAuthorizationHandlerProviderwird standardmäßig hinzugefügt, wennAddAuthorizationverwendet wird, und Dienste werden mitIServiceProviderIsServiceerkannt. - Benutzerkonfigurierte Middleware und Endpunkte werden zwischen
UseRoutingundUseEndpointshinzugefügt.
Der folgende Code entspricht effektiv dem, was die automatische Middleware, die zur App hinzugefügt wird, erzeugt.
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 einigen Fällen eignet sich die standardmäßige Middleware-Konfiguration nicht für die App und muss geändert werden. Beispielsweise sollte UseCors vor UseAuthentication und UseAuthorization aufgerufen werden. Die App muss UseAuthentication und UseAuthorization aufrufen, wenn UseCors aufgerufen wird:
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
Wenn Middleware ausgeführt werden muss, bevor der Routenabgleich erfolgt, muss UseRouting aufgerufen werden, und die Middleware muss vor dem Aufruf von UseRouting platziert werden.
UseEndpoints ist in diesem Fall nicht erforderlich, da es wie zuvor beschrieben automatisch hinzugefügt wird:
app.Use((context, next) =>
{
return next(context);
});
app.UseRouting();
// other middleware and endpoints
Beim Hinzufügen einer Terminal-Middleware:
- Die Middleware muss nach
UseEndpointshinzugefügt werden. - Die App muss
UseRoutingundUseEndpointsaufrufen, damit die Terminal-Middleware an der richtigen Position platziert werden kann.
app.UseRouting();
app.MapGet("/", () => "hello world");
app.UseEndpoints(e => {});
app.Run(context =>
{
context.Response.StatusCode = 404;
return Task.CompletedTask;
});
Terminal-Middleware ist Middleware, die ausgeführt wird, wenn kein Endpunkt die Anforderung verarbeitet.
WebApplication fügt automatisch die folgende Middleware in ASP.NET Core Apps hinzu, je nach bestimmten Bedingungen:
UseDeveloperExceptionPage wird zuerst hinzugefügt, wenn das HostingEnvironment
"Development"ist.UseRouting wird als zweites hinzugefügt, wenn der Benutzercode nicht bereits
UseRoutingaufgerufen hat und Endpunkte konfiguriert sind, z. B.app.MapGet.UseEndpoints wird am Ende der Middleware-Pipeline hinzugefügt, wenn Endpunkte konfiguriert sind.
UseAuthentication wird unmittelbar nach
UseRoutinghinzugefügt, wenn der Benutzercode nicht bereitsUseAuthenticationaufgerufen hat und wenn IAuthenticationSchemeProvider im Dienstanbieter erkannt werden kann.IAuthenticationSchemeProviderwird standardmäßig hinzugefügt, wenn Sie AddAuthentication verwenden, und Dienste werden mithilfe von IServiceProviderIsService erkannt.UseAuthorization wird als Nächstes hinzugefügt, wenn der Benutzercode noch nicht
UseAuthorizationaufgerufen hat und wenn IAuthorizationHandlerProvider im Dienstanbieter erkannt werden kann.IAuthorizationHandlerProviderwird standardmäßig hinzugefügt, wenn Sie AddAuthorization verwenden, und Dienste werden mithilfe vonIServiceProviderIsServiceermittelt.Benutzerkonfigurierte Middleware und Endpunkte werden zwischen
UseRoutingundUseEndpointshinzugefügt.
Der folgende Code entspricht effektiv dem, was die automatische Middleware, die zur App hinzugefügt wird, erzeugt.
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 einigen Fällen eignet sich die standardmäßige Middleware-Konfiguration nicht für die App und muss geändert werden. Beispielsweise sollte UseCors vor UseAuthentication und UseAuthorization aufgerufen werden. Die App muss UseAuthentication und UseAuthorization aufrufen, wenn UseCors aufgerufen wird:
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
Wenn Middleware ausgeführt werden muss, bevor der Routenabgleich erfolgt, muss UseRouting aufgerufen werden, und die Middleware muss vor dem Aufruf von UseRouting platziert werden.
UseEndpoints ist in diesem Fall nicht erforderlich, da sie wie zuvor beschrieben automatisch hinzugefügt wird:
app.Use((context, next) =>
{
return next(context);
});
app.UseRouting();
// Other middleware and endpoints
Beim Hinzufügen einer Terminal-Middleware:
Die Middleware muss nach
UseEndpointshinzugefügt werden.Die App muss
UseRoutingundUseEndpointsaufrufen, damit die Terminal-Middleware an der richtigen Stelle platziert werden kann.
app.UseRouting();
app.MapGet("/", () => "hello world");
app.UseEndpoints(e => {});
app.Run(context =>
{
context.Response.StatusCode = 404;
return Task.CompletedTask;
});
Terminal-Middleware ist Middleware, die ausgeführt wird, wenn kein Endpunkt die Anforderung verarbeitet.
Informationen zu Antiforgery-Middleware in minimalen APIs finden Sie unter Prevent Cross-Site Request Forgery (XSRF/CSRF)-Angriffe in ASP.NET Core.
Reihenfolge der Middleware
Die Reihenfolge, in der Middleware in der App-Datei Program angezeigt wird, definiert die Reihenfolge, in der Middleware für eine Anforderung mit der umgekehrten Reihenfolge für die Antwort aufgerufen wird.
Sie haben die volle Kontrolle über die Reihenfolge der Middleware und die Möglichkeit, benutzerdefinierte Middleware für Anforderungsverarbeitungsszenarien hinzuzufügen, und beachten Sie, dass die Reihenfolge der Middleware für Sicherheit, Leistung und Funktionalität von entscheidender Bedeutung sein kann.
Die folgenden Beispiele veranschaulichen die Middlewarereihenfolge für allgemeine App-Szenarien. Jede Middleware-Erweiterungsmethode wird im WebApplicationBuilder-Namespace über Microsoft.AspNetCore.Builder verfügbar gemacht.
- Ausnahme- und Fehlerbehandlung
- Wenn die App in der
DevelopmentUmgebung ausgeführt wird:- Die Middleware für Entwicklerausnahmeseiten (UseDeveloperExceptionPage) zeigt Laufzeitfehler der App an.
- Middleware für Datenbankfehlerseiten (UseDatabaseErrorPage) meldet Datenbank-Laufzeitfehler.
- Wenn die App in der
ProductionUmgebung ausgeführt wird:- Ausnahmehandler Middleware (UseExceptionHandler) fängt Ausnahmen ab, die in den folgenden Middlewares ausgelöst werden.
- HTTP Strict Transport Security (HSTS)-Protokoll-Middleware (UseHsts) fügt den
Strict-Transport-SecurityHeader hinzu.
- Wenn die App in der
- HTTPS-Umleitungs-Middleware (UseHttpsRedirection) leitet HTTP-Anforderungen an HTTPS um.
- Middleware für statische Dateien (falls erforderlich, UseStaticFiles) gibt statische Dateien zurück und beendet die weitere Anforderungsverarbeitung vorzeitig.
- Cookie Policy Middleware (UseCookiePolicy) entspricht der App der EU-Datenschutz-Grundverordnung (DSGVO).
- Routing-Middleware (UseRouting) zum Weiterleiten von Anfragen.
- Authentifizierungs-Middleware (UseAuthentication) versucht, den Benutzer zu authentifizieren, bevor er Zugriff auf sichere Ressourcen hat.
- Autorisierungs-Middleware (UseAuthorization) autorisiert einen Benutzer für den Zugriff auf sichere Ressourcen.
- Das Antiforgery-Middleware (UseAntiforgery) fügt der Pipeline UseAntiforgery Antiforgery-Middleware hinzu und muss hinter den Aufrufen von UseAuthentication und UseAuthorization platziert werden.
- Die Session-Middleware (Razor nur Pages und MVC, UseSession) richtet den Sitzungszustand ein und verwaltet ihn. Wenn die App den Sitzungsstatus verwendet, rufen Sie die Sitzungs-Middleware nach der cookie-Policy-Middleware und vor der Middleware für Razor Pages/MVC auf.
- Middleware für Endpunktrouting
- MapRazorComponents zum Hinzufügen von Razor Komponentenendpunkten zur Anforderungspipeline.
- MapRazorPages zum Hinzufügen von Razor Pages-Endpoints zur Anforderungspipeline.
- MapControllerRoute zum Hinzufügen von Controllerendpunkten zur Anforderungspipeline.
Typische Blazor Web App Middleware-Pipeline:
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();
Im vorhergehenden Code:
- CORS Middleware (UseCors), Authentifizierungs-Middleware (UseAuthentication) und Autorisierungs-Middleware (UseAuthorization) müssen in der angezeigten Reihenfolge angezeigt werden.
- CORS-Middleware (UseCors) muss vor der Antwortzwischenspeicherungs-Middleware (UseResponseCaching) stehen, um CORS-Header zu jeder Anfrage hinzuzufügen, einschließlich zwischengespeicherter Antworten. Weitere Informationen finden Sie unter Es ist nicht klar, dass UseCORS vor UseResponseCaching (
dotnet/aspnetcore#23218) kommen muss. - Die Lokalisierungs-Middleware (UseRequestLocalization) muss vor jeder Middleware angezeigt werden, die die Anforderungskultur überprüfen kann, z. B. statische Datei-Middleware (UseStaticFiles).
- Middleware zur Ratenbegrenzung (UseRateLimiter) muss nach der Routing-Middleware (UseRouting) aufgerufen werden, wenn endpunktspezifische APIs zur Ratenbegrenzung verwendet werden. Wenn z. B. das
[EnableRateLimiting]Attribut verwendet wird, muss die Ratenbegrenzungs-Middleware nach der Routing-Middleware aufgerufen werden. Wenn nur globale Limiter aufgerufen werden, kann die Rate-Limiting-Middleware vor der Routing-Middleware aufgerufen werden.
In einigen Szenarien weist die Middleware eine andere Reihenfolge auf. Beispielsweise hängt die Zwischenspeicherung und Komprimierungsordnung von der Spezifikation der App ab. In der folgenden Reihenfolge kann die CPU-Auslastung reduziert werden, indem die komprimierte Antwort zwischengespeichert wird. Die App kann jedoch mehrere Darstellungen einer Ressource mit unterschiedlichen Komprimierungsalgorithmen wie Gzip oder Brotli zwischenspeichern:
app.UseResponseCaching();
app.UseResponseCompression();
Statische Ressourcen werden in der Regel frühzeitig in der Pipeline bereitgestellt, sodass die App die Verarbeitung von Anfragen abkürzen kann, um die Leistung zu verbessern.
Die Authentifizierung schließt nicht authentifizierte Anforderungen nicht kurz. Obwohl Authentifizierungsmiddleware Anfragen authentifiziert, erfolgt die Autorisierung erst, nachdem das Framework eine Razor-Komponente in einer Blazor Web App-App, eine Seite in einer Razor-App oder einen Controller und eine Aktion in einer MVC-App ausgewählt hat.
In der folgenden Abbildung wird die gesamte Anforderungsverarbeitungspipeline für MVC- und Razor Pages-Apps in ASP.NET Core dargestellt. Es ist zu sehen, wie vorhandene Middleware in einer typischen App sortiert ist und an welcher Stelle benutzerdefinierte Middleware hinzugefügt wird. Sie haben vollständige Kontrolle darüber, wie vorhandene Middleware-Komponenten neu angeordnet oder neue benutzerdefinierte Middleware-Komponenten nach Bedarf eingefügt werden.
Der Endpunktmiddleware in der vorangehenden Abbildung führt die Filterpipeline für den entsprechenden App-Typ aus (MVC oder Razor Pages).
Das vorangehende Diagramm zeigt, dass die Routing-Middleware auf statische Dateien folgt. In dieser Reihenfolge funktionieren die Projektvorlagen, indem app.UseRouting explizit aufgerufen wird. Wenn Sie nicht app.UseRouting aufrufen, wird die Routing-Middleware standardmäßig am Anfang der Pipeline ausgeführt. Weitere Informationen finden Sie unter Routing.
Die Reihenfolge, in der Sie Middleware-Komponenten in der Program.cs Datei hinzufügen, definiert die Reihenfolge, in der die Middleware-Komponenten für Anforderungen und die umgekehrte Reihenfolge für die Antwort aufgerufen werden. Die Reihenfolge ist in Bezug auf Sicherheit, Leistung und Funktionalität entscheidend.
Der folgende hervorgehobene Code in Program.cs fügt sicherheitsbezogene Middlewarekomponenten in der typischen empfohlenen Reihenfolge hinzu:
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();
Im vorhergehenden Code:
- Auskommentierte Middleware wird nicht hinzugefügt, wenn Sie eine neue Web-App mit einzelnen Benutzerkonten erstellen.
- Die exakte Reihenfolge ist nicht für jede Middleware vorgeschrieben (dies ist jedoch meistens der Fall). Beispiel:
-
UseCors,UseAuthenticationundUseAuthorizationmüssen in der angezeigten Reihenfolge stehen. -
UseCorsmuss derzeit vorUseResponseCachingstehen. Diese Anforderung wird im GitHub-Issue zu dotnet/aspnetcore, Nr. 23218, erläutert. -
UseRequestLocalizationmuss vor jeder Middleware stehen, die u. U. die Anforderungskultur überprüft (z. B.app.UseStaticFiles()). -
UseRateLimiter muss nach
UseRoutingaufgerufen werden, wenn endpunktspezifische APIs für die Ratenbegrenzung verwendet werden. Wenn zum Beispiel das Attribut[EnableRateLimiting]verwendet wird, mussUseRateLimiternachUseRoutingaufgerufen werden. Wenn nur globale Begrenzungen aufgerufen werden,UseRateLimiterkann vorUseRoutingaufgerufen werden.
-
In einigen Szenarien weist die Middleware eine andere Reihenfolge auf. Die Reihenfolge für Zwischenspeicherung und Komprimierung beispielsweise ist szenariospezifisch, und es gibt verschiedene gültige Reihenfolgen. Beispiel:
app.UseResponseCaching();
app.UseResponseCompression();
Mit dem vorherigen Code können Sie die CPU-Auslastung reduzieren, indem Sie die komprimierte Antwort zwischenspeichern, aber Sie können mehrere Darstellungen einer Ressource mithilfe verschiedener Komprimierungsalgorithmen wie Gzip oder Brotli zwischenspeichern.
Die folgende Reihenfolge kombiniert statische Dateien, um eine Zwischenspeicherung komprimierter statischer Dateien zuzulassen:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();
Der folgende Program.cs-Code fügt Middlewarekomponenten für allgemeine App-Szenarios hinzu:
- Ausnahme- und Fehlerbehandlung
- Wenn die App in der
DevelopmentUmgebung ausgeführt wird:- Die Middleware für Entwicklerausnahmeseiten (UseDeveloperExceptionPage) zeigt Laufzeitfehler der App an.
- Middleware für Datenbankfehlerseiten (UseDatabaseErrorPage) meldet Datenbank-Laufzeitfehler.
- Wenn die App in der
ProductionUmgebung ausgeführt wird:- Ausnahmehandler Middleware (UseExceptionHandler) fängt Ausnahmen ab, die in den folgenden Middlewares ausgelöst werden.
- HTTP Strict Transport Security (HSTS)-Protokoll-Middleware (UseHsts) fügt den
Strict-Transport-SecurityHeader hinzu.
- Wenn die App in der
- HTTPS-Umleitungs-Middleware (UseHttpsRedirection) leitet HTTP-Anforderungen an HTTPS um.
- Die Middleware für statische Dateien (UseStaticFiles) gibt statische Dateien zurück und beendet die weitere Anforderungsverarbeitung vorzeitig.
- Cookie Richtlinien-Middleware (UseCookiePolicy) bringt die App mit den Vorgaben der EU-Datenschutz-Grundverordnung (DSGVO) in Einklang.
- Routing-Middleware (UseRouting) zum Weiterleiten von Anfragen.
- Authentifizierungs-Middleware (UseAuthentication) versucht, den Benutzer zu authentifizieren, bevor er Zugriff auf sichere Ressourcen hat.
- Autorisierungs-Middleware (UseAuthorization) autorisiert einen Benutzer für den Zugriff auf sichere Ressourcen.
- Die Sessionmiddleware (UseSession) initialisiert und verwaltet den Sitzungszustand. Wenn die App den Sitzungsstatus verwendet, rufen Sie die Middleware für Sitzungen nach der Middleware für cookie-Richtlinien und vor der MVC-Middleware auf.
- Endpunktroutingmiddleware (UseEndpoints mit MapRazorPages) zum Hinzufügen von Razor Pages-Endpunkten zur Anforderungspipeline.
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();
Im vorhergehenden Beispielcode wird jede Middleware-Erweiterungsmethode in WebApplicationBuilder über den Microsoft.AspNetCore.Builder-Namespace verfügbar gemacht.
UseExceptionHandler ist die erste Middlewarekomponente, die der Pipeline hinzugefügt wird. Daher fängt die Middleware des Ausnahmehandlers alle Ausnahmen ab, die in späteren Aufrufen auftreten.
Die Middleware für statische Dateien wird am Anfang der Pipeline aufgerufen, damit sie Anforderungen und Kurzschlüsse verarbeiten kann, ohne dass die verbleibenden Komponenten durchlaufen werden müssen. Die statische Datei-Middleware stellt keine Autorisierungsprüfungen bereit. Alle Dateien, die von statischer Datei-Middleware bereitgestellt werden, einschließlich der Dateien unter wwwroot, sind öffentlich verfügbar. Im Artikel zu statischen Dateien in ASP.NET Core erfahren Sie, wie Sie statische Dateien schützen können.
Wenn die Anforderung nicht von der statischen Datei-Middleware behandelt wird, wird sie an die Authentifizierungs-Middleware (UseAuthentication) übergeben, die Authentifizierung durchführt. Die Authentifizierung schließt nicht authentifizierte Anforderungen nicht kurz. Obwohl die Authentifizierungs-Middleware Anforderungen authentifiziert, tritt autorisierung (und Ablehnung) erst auf, nachdem MVC einen bestimmten Page- oder MVC-Controller und eine bestimmte Razor Aktion ausgewählt hat.
Im folgenden Beispiel wird eine Middleware-Reihenfolge veranschaulicht, in der Anforderungen für statische Dateien von statischer Datei-Middleware vor der Middleware für die Reaktionskomprimierung behandelt werden. Die statischen Dateien werden in dieser Reihenfolge der Middleware nicht komprimiert. Die Razor Pages-Antworten können komprimiert werden.
// Static files aren't compressed by static file middleware.
app.UseStaticFiles();
app.UseRouting();
app.UseResponseCompression();
app.MapRazorPages();
In der folgenden Abbildung wird die gesamte Anforderungsverarbeitungspipeline für MVC- und Razor Pages-Apps in ASP.NET Core dargestellt. Es ist zu sehen, wie vorhandene Middleware in einer typischen App sortiert ist und an welcher Stelle benutzerdefinierte Middleware hinzugefügt wird. Sie haben vollständige Kontrolle darüber, wie vorhandene Middleware-Komponenten neu angeordnet oder neue benutzerdefinierte Middleware-Komponenten nach Bedarf eingefügt werden.
Der Endpunktmiddleware in der vorangehenden Abbildung führt die Filterpipeline für den entsprechenden App-Typ aus (MVC oder Razor Pages).
Das vorstehende Diagramm zeigt, dass die Routing-Middleware auf statische Dateien folgt. In dieser Reihenfolge funktionieren die Projektvorlagen durch explizite Aufrufe von app.UseRouting. Wenn Sie nicht app.UseRouting aufrufen, wird die Routing-Middleware standardmäßig am Anfang der Pipeline ausgeführt. Weitere Informationen finden Sie unter Routing.
Die Reihenfolge, in der Sie Middleware-Komponenten in der Program.cs Datei hinzufügen, definiert die Reihenfolge, in der die Middleware-Komponenten für Anforderungen und die umgekehrte Reihenfolge für die Antwort aufgerufen werden. Die Reihenfolge ist in Bezug auf Sicherheit, Leistung und Funktionalität entscheidend.
Der folgende hervorgehobene Code in Program.cs fügt sicherheitsbezogene Middlewarekomponenten in der typischen empfohlenen Reihenfolge hinzu:
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();
Im vorhergehenden Code:
- Auskommentierte Middleware wird nicht hinzugefügt, wenn Sie eine neue Web-App mit einzelnen Benutzerkonten erstellen.
- Die exakte Reihenfolge ist nicht für jede Middleware vorgeschrieben (dies ist jedoch meistens der Fall). Beispiel:
-
UseCors,UseAuthenticationundUseAuthorizationmüssen in der angezeigten Reihenfolge stehen. -
UseCorsmuss derzeit vorUseResponseCachingstehen. Diese Anforderung wird im GitHub-Issue zu dotnet/aspnetcore, Nr. 23218, erläutert. -
UseRequestLocalizationmuss vor jeder Middleware stehen, die u. U. die Anforderungskultur überprüft (z. B.app.UseMvcWithDefaultRoute()).
-
In einigen Szenarien weist die Middleware eine andere Reihenfolge auf. Die Reihenfolge für Zwischenspeicherung und Komprimierung beispielsweise ist szenariospezifisch, und es gibt verschiedene gültige Reihenfolgen. Beispiel:
app.UseResponseCaching();
app.UseResponseCompression();
Mit dem vorherigen Code können Sie die CPU-Auslastung reduzieren, indem Sie die komprimierte Antwort zwischenspeichern, aber Sie können mehrere Darstellungen einer Ressource mithilfe verschiedener Komprimierungsalgorithmen wie Gzip oder Brotli zwischenspeichern.
Die folgende Reihenfolge kombiniert statische Dateien, um eine Zwischenspeicherung komprimierter statischer Dateien zuzulassen:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();
Der folgende Program.cs-Code fügt Middlewarekomponenten für allgemeine App-Szenarios hinzu:
- Ausnahme- und Fehlerbehandlung
- Wenn die App in der
DevelopmentUmgebung ausgeführt wird:- Die Middleware für Entwicklerausnahmeseiten (UseDeveloperExceptionPage) zeigt Laufzeitfehler der App an.
- Middleware für Datenbankfehlerseiten (UseDatabaseErrorPage) meldet Datenbank-Laufzeitfehler.
- Wenn die App in der
ProductionUmgebung ausgeführt wird:- Ausnahmehandler Middleware (UseExceptionHandler) fängt Ausnahmen ab, die in den folgenden Middlewares ausgelöst werden.
- HTTP Strict Transport Security (HSTS)-Protokoll-Middleware (UseHsts) fügt den
Strict-Transport-SecurityHeader hinzu.
- Wenn die App in der
- HTTPS-Umleitungs-Middleware (UseHttpsRedirection) leitet HTTP-Anforderungen an HTTPS um.
- Die Middleware für statische Dateien (UseStaticFiles) gibt statische Dateien zurück und beendet die weitere Anforderungsverarbeitung vorzeitig.
- Cookie Richtlinien-Middleware (UseCookiePolicy) bringt die App mit den Vorgaben der EU-Datenschutz-Grundverordnung (DSGVO) in Einklang.
- Routing-Middleware (UseRouting) zum Weiterleiten von Anfragen.
- Authentifizierungs-Middleware (UseAuthentication) versucht, den Benutzer zu authentifizieren, bevor er Zugriff auf sichere Ressourcen hat.
- Autorisierungs-Middleware (UseAuthorization) autorisiert einen Benutzer für den Zugriff auf sichere Ressourcen.
- Die Sessionmiddleware (UseSession) initialisiert und verwaltet den Sitzungszustand. Wenn die App den Sitzungsstatus verwendet, rufen Sie die Middleware für Sitzungen nach der Middleware für cookie-Richtlinien und vor der MVC-Middleware auf.
- Endpunktroutingmiddleware (UseEndpoints mit MapRazorPages) zum Hinzufügen von Razor Pages-Endpunkten zur Anforderungspipeline.
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();
Im vorhergehenden Beispielcode wird jede Middleware-Erweiterungsmethode in WebApplicationBuilder über den Microsoft.AspNetCore.Builder-Namespace verfügbar gemacht.
UseExceptionHandler ist die erste Middlewarekomponente, die der Pipeline hinzugefügt wird. Daher fängt die Middleware des Ausnahmehandlers alle Ausnahmen ab, die in späteren Aufrufen auftreten.
Die Middleware für statische Dateien wird am Anfang der Pipeline aufgerufen, damit sie Anforderungen und Kurzschlüsse verarbeiten kann, ohne dass die verbleibenden Komponenten durchlaufen werden müssen. Die statische Datei-Middleware stellt keine Autorisierungsprüfungen bereit. Alle Dateien, die von statischer Datei-Middleware bereitgestellt werden, einschließlich der Dateien unter wwwroot, sind öffentlich verfügbar. Im Artikel zu statischen Dateien in ASP.NET Core erfahren Sie, wie Sie statische Dateien schützen können.
Wenn die Anforderung nicht von der statischen Datei-Middleware behandelt wird, wird sie an die Authentifizierungs-Middleware (UseAuthentication) übergeben, die Authentifizierung durchführt. Die Authentifizierung schließt nicht authentifizierte Anforderungen nicht kurz. Obwohl die Authentifizierungs-Middleware Anforderungen authentifiziert, tritt autorisierung (und Ablehnung) erst auf, nachdem MVC einen bestimmten Page- oder MVC-Controller und eine bestimmte Razor Aktion ausgewählt hat.
Im folgenden Beispiel wird eine Middleware-Reihenfolge veranschaulicht, in der Anforderungen für statische Dateien von statischer Datei-Middleware vor der Middleware für die Reaktionskomprimierung behandelt werden. Die statischen Dateien werden in dieser Reihenfolge der Middleware nicht komprimiert. Die Razor Pages-Antworten können komprimiert werden.
// Static files aren't compressed by static file middleware.
app.UseStaticFiles();
app.UseRouting();
app.UseResponseCompression();
app.MapRazorPages();
In der folgenden Abbildung wird die gesamte Anforderungsverarbeitungspipeline für MVC- und Razor Pages-Apps in ASP.NET Core dargestellt. Es ist zu sehen, wie vorhandene Middleware in einer typischen App sortiert ist und an welcher Stelle benutzerdefinierte Middleware hinzugefügt wird. Sie haben vollständige Kontrolle darüber, wie vorhandene Middleware-Komponenten neu angeordnet oder neue benutzerdefinierte Middleware-Komponenten nach Bedarf eingefügt werden.
Der Endpunktmiddleware in der vorangehenden Abbildung führt die Filterpipeline für den entsprechenden App-Typ aus (MVC oder Razor Pages).
Die Reihenfolge, in der Middlewarekomponenten in der Startup.Configure-Methode hinzugefügt werden, legt die Reihenfolge fest, in der die Middlewarekomponenten bei Anforderungen aufgerufen werden. Bei Antworten gilt die umgekehrte Reihenfolge. Die Reihenfolge ist in Bezug auf Sicherheit, Leistung und Funktionalität entscheidend.
Die folgende Startup.Configure-Methode fügt sicherheitsbezogene Middlewarekomponenten in der typischen empfohlenen Reihenfolge hinzu:
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?}");
});
}
Im vorhergehenden Code:
- Auskommentierte Middleware wird nicht hinzugefügt, wenn Sie eine neue Web-App mit einzelnen Benutzerkonten erstellen.
- Die exakte Reihenfolge ist nicht für jede Middleware vorgeschrieben (dies ist jedoch meistens der Fall). Beispiel:
-
UseCors,UseAuthenticationundUseAuthorizationmüssen in der angezeigten Reihenfolge stehen. -
UseCorsmuss derzeit vorUseResponseCachingstehen, aufgrund dieses Bugs. -
UseRequestLocalizationmuss vor jeder Middleware stehen, die u. U. die Anforderungskultur überprüft (z. B.app.UseMvcWithDefaultRoute()).
-
In einigen Szenarien weist die Middleware eine andere Reihenfolge auf. Die Reihenfolge für Zwischenspeicherung und Komprimierung beispielsweise ist szenariospezifisch, und es gibt verschiedene gültige Reihenfolgen. Beispiel:
app.UseResponseCaching();
app.UseResponseCompression();
Mit dem obigen Code könnte durch Zwischenspeichern der komprimierten Antwort die CPU-Auslastung verringert werden, dies könnte aber dazu führen, dass mehrere Darstellungen einer Ressource mithilfe verschiedener Komprimierungsalgorithmen wie z. B. Gzip oder Brotli zwischengespeichert werden.
Die folgende Reihenfolge kombiniert statische Dateien, um eine Zwischenspeicherung komprimierter statischer Dateien zuzulassen:
app.UseResponseCaching();
app.UseResponseCompression();
app.UseStaticFiles();
Die folgenden Startup.Configure-Methode fügt Middlewarekomponenten für allgemeine App-Szenarien hinzu:
- Ausnahme- und Fehlerbehandlung
- Wenn die App in der
DevelopmentUmgebung ausgeführt wird:- Die Middleware für Entwicklerausnahmeseiten (UseDeveloperExceptionPage) zeigt Laufzeitfehler der App an.
- Die Middleware-Datenbankfehlerseite meldet Datenbanklaufzeitfehler.
- Wenn die App in der
ProductionUmgebung ausgeführt wird:- Ausnahmehandler Middleware (UseExceptionHandler) fängt Ausnahmen ab, die in den folgenden Middlewares ausgelöst werden.
- HTTP Strict Transport Security (HSTS)-Protokoll-Middleware (UseHsts) fügt den
Strict-Transport-SecurityHeader hinzu.
- Wenn die App in der
- HTTPS-Umleitungs-Middleware (UseHttpsRedirection) leitet HTTP-Anforderungen an HTTPS um.
- Die Middleware für statische Dateien (UseStaticFiles) gibt statische Dateien zurück und beendet die weitere Anforderungsverarbeitung vorzeitig.
- Cookie Richtlinien-Middleware (UseCookiePolicy) bringt die App mit den Vorgaben der EU-Datenschutz-Grundverordnung (DSGVO) in Einklang.
- Routing-Middleware (UseRouting) zum Weiterleiten von Anfragen.
- Authentifizierungs-Middleware (UseAuthentication) versucht, den Benutzer zu authentifizieren, bevor er Zugriff auf sichere Ressourcen hat.
- Autorisierungs-Middleware (UseAuthorization) autorisiert einen Benutzer für den Zugriff auf sichere Ressourcen.
- Die Sessionmiddleware (UseSession) initialisiert und verwaltet den Sitzungszustand. Wenn die App den Sitzungsstatus verwendet, rufen Sie die Middleware für Sitzungen nach der Middleware für cookie-Richtlinien und vor der MVC-Middleware auf.
- Endpunktroutingmiddleware (UseEndpoints mit MapRazorPages) zum Hinzufügen von Razor Pages-Endpunkten zur Anforderungspipeline.
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();
});
}
Im vorhergehenden Beispielcode wird jede Middleware-Erweiterungsmethode in IApplicationBuilder über den Microsoft.AspNetCore.Builder-Namespace verfügbar gemacht.
UseExceptionHandler ist die erste Middlewarekomponente, die der Pipeline hinzugefügt wird. Daher fängt die Middleware des Ausnahmehandlers alle Ausnahmen ab, die in späteren Aufrufen auftreten.
Die Middleware für statische Dateien wird am Anfang der Pipeline aufgerufen, damit sie Anforderungen und Kurzschlüsse verarbeiten kann, ohne dass die verbleibenden Komponenten durchlaufen werden müssen. Die statische Datei-Middleware stellt keine Autorisierungsprüfungen bereit. Alle Dateien, die von statischer Datei-Middleware bereitgestellt werden, einschließlich der Dateien unter wwwroot, sind öffentlich verfügbar. Im Artikel zu statischen Dateien in ASP.NET Core erfahren Sie, wie Sie statische Dateien schützen können.
Wenn die Anforderung nicht von der statischen Datei-Middleware behandelt wird, wird sie an die Authentifizierungs-Middleware (UseAuthentication) übergeben, die Authentifizierung durchführt. Die Authentifizierung schließt nicht authentifizierte Anforderungen nicht kurz. Obwohl die Authentifizierungs-Middleware Anforderungen authentifiziert, tritt autorisierung (und Ablehnung) erst auf, nachdem MVC einen bestimmten Page- oder MVC-Controller und eine bestimmte Razor Aktion ausgewählt hat.
Im folgenden Beispiel wird eine Middleware-Reihenfolge veranschaulicht, in der Anforderungen für statische Dateien von statischer Datei-Middleware vor der Middleware für die Reaktionskomprimierung behandelt werden. Die statischen Dateien werden in dieser Reihenfolge der Middleware nicht komprimiert. Die Razor Pages-Antworten können komprimiert werden.
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();
});
}
Bei Single-Page-Webanwendungen (Single-Page Applications, SPAs) ist die entsprechende SPA-Middleware UseSpaStaticFiles in der Regel der letzte Teil der Middlewarepipeline. Die SPA-Middleware steht an letzter Stelle.
- Damit alle anderen Middleware zuerst auf übereinstimmende Anforderungen reagieren können.
- Damit SPAs mit clientseitigem Routing für alle Routen ausgeführt werden können, die von der Server-App nicht erkannt werden.
Weitere Informationen zu SPAs finden Sie in den Anleitungen zu den React- und Angular-Projektvorlagen.
Weitere Informationen zu Single-Page-Anwendungen finden Sie in den Anleitungen zu den React- und Angular-Projektvorlagen.
UseCors und UseStaticFiles Reihenfolge
Weitere Informationen zum Bestellen von UseCors und UseStaticFiles finden Sie unter Aktivieren von Cross-Origin Requests (CORS) in ASP.NET Core.
Middleware für weitergeleitete Header: Auftrag
Führen Sie die Middleware für weitergeleitete Header vor anderer Middleware aus, um sicherzustellen, dass Middleware, die auf Informationen aus weitergeleiteten Headern angewiesen ist, die Headerwerte zur Verarbeitung nutzen kann. Wenn Sie wissen möchten, wie Middleware für Weitergeleitete Header nach Middleware für Diagnose und Fehlerbehebung ausgeführt wird, finden Sie weitere Informationen unter Middleware für weitergeleitete Header – Reihenfolge.
Integrierte Middleware
Die neueste Version von ASP.NET Core enthält die folgende Middleware. Die Spalte für den UI-Stapel zeigt den typischen UI-Stapel an, in dem die Middleware verwendet wird: [Alle, Blazor Web App (BWA), Razor Seiten und MVC (RP/MVC)]. Die Spalte "Bestellung " enthält Hinweise zur Middleware-Platzierung in der Anforderungsverarbeitungspipeline und unter welchen Bedingungen die Middleware die Anforderungsverarbeitung beenden kann. Wenn eine Middleware einen Kurzschluss in der Anforderungsverarbeitungspipeline verursacht und verhindert, dass Downstreammiddleware eine Anforderung verarbeitet, wird diese als Terminalmiddleware bezeichnet. Weitere Informationen zum Kurzschluss finden Sie unter " Erstellen einer Middleware-Pipeline mit WebApplication Abschnitt".
| Middleware | Beschreibung | UI-Stapel | Auftrag |
|---|---|---|---|
| Antiforgerie | Bietet Unterstützung für Anti-request-forgery-Schutz | All | Nach Authentifizierung und Autorisierung, vor Endpunkten. |
| Authentifizierung | Bietet Unterstützung für Authentifizierungen. | All | Vorher ist HttpContext.User erforderlich. Terminal für OAuth-Rückrufe. |
| Autorisierung | Bietet Unterstützung für Authentifizierungen | All | Unmittelbar nach der Authentifizierungs-Middleware. |
| Cookierichtlinie | Verfolgt die Zustimmung von Benutzern zum Speichern persönlicher Informationen und erzwingt die Mindeststandards für cookiefelder, z. B. secure und SameSite. |
All | Vor der Middleware, die Cookies ausstellt. Beispiele: Authentifizierung, Sitzung, MVC (TempData). |
| CORS | Konfiguriert die Ressourcenfreigabe zwischen verschiedenen Ursprüngen (Cross-Origin Resource Sharing, CORS). | All | Vor Middleware, die CORS verwenden.
UseCors muss vor UseResponseCaching stehen. Weitere Informationen finden Sie unter Es ist nicht klar, dass UseCORS vor UseResponseCaching (dotnet/aspnetcore #23218) kommen muss. |
| die Seite mit Ausnahmen für Entwickler | Generiert eine Seite mit Fehlerinformationen, die nur in der Development Umgebung verwendet werden sollen. |
All | Vor Middleware, die Fehler generiert. Die Projektvorlagen registrieren diese Middleware automatisch als erste Middleware in der Pipeline, wenn die Umgebung Development ist. |
| Diagnose | Mehrere separate Middlewares, die Entwicklern eine Ausnahmeseite, Ausnahmebehandlung, Statuscodeseiten und die Standardwebseite für neue Apps bereitstellen. | All | Vor Middleware, die Fehler generiert. Terminal für Ausnahmen oder zum Bereitstellen der Standardwebseite für neue Apps. |
| Weitergeleitete Header | Leitet die Proxy-Header an die aktuelle Anforderung weiter. | All | Vor Middleware, die die aktualisierten Felder nutzt. Beispiele: Schema, Host, Client-IP, Methode. |
| Integritätsprüfung | Überprüft die Integrität der ASP.NET Core-App und ihrer Abhängigkeiten, z. B. Überprüfung der Datenbankverfügbarkeit. | All | Abschließend, wenn eine Anforderung mit einem Integritätsprüfungs-Endpunkt übereinstimmt. |
| Headerweitergabe | Überträgt HTTP-Header aus der eingehenden Anforderung zu ausgehenden HTTP-Clientanforderungen | ||
| All | |||
| HTTP-Protokollierung | Hiermit werden HTTP-Anforderungen und -Antworten protokolliert. | All | Am Anfang der Middleware-Pipeline. |
| Außerkraftsetzung der HTTP-Methode | Ermöglicht es eingehenden POST-Anforderungen, die Methode außer Kraft zu setzen. | All | Vor Middleware, die die aktualisierte Methode nutzt. |
| HTTPS-Umleitung | Leitet alle HTTP-Anforderungen an HTTPS um. | All | Vor der Middleware, die die URL verarbeitet. |
| HTTP Strict Transport Security (HSTS) | Middleware für erweiterte Sicherheit, die einen besonderen Antwortheader hinzufügt. | All | Bevor Antworten gesendet werden und nach dem Einsatz von Middleware, die Anfragen modifiziert. Beispiele: Forwarded Headers, URL-Rewriting. |
| MVC | Verarbeitet Anfragen mit MVC und Razor Pages. | RP/MVC | Endpunkt, wenn eine Anforderung mit einer Route übereinstimmt. |
| OWIN | Interoperabilität mit auf OWIN basierten Apps, Servern und Middleware. | RP/MVC | Terminal, wenn die OWIN Middleware die Anforderung vollständig verarbeitet. |
| Ausgabezwischenspeicherung | Bietet Unterstützung für das Zwischenspeichern von Antworten basierend auf der Konfiguration. | RP/MVC | Vor Middleware, die eine Zwischenspeicherung erfordert. UseRouting, UseCors, UseAuthenticationund UseAuthorization muss vor UseOutputCache. |
| Antwort-Cache | Bietet Unterstützung für das Zwischenspeichern von Antworten. Diese Middleware erfordert, dass die Clientbeteiligung funktioniert. Verwenden Sie Ausgabezwischenspeicherung für vollständige Serversteuerung. | RP/MVC | Vor Middleware, die eine Zwischenspeicherung erfordert. UseCors muss sich vor UseResponseCaching befinden. Das Zwischenspeichern von Antworten ist in der Regel für UI-Apps wie Razor Seiten nicht von Vorteil, da Browser in der Regel Anforderungsheader festlegen, die das Zwischenspeichern verhindern. Benutzeroberflächen-Apps profitieren von Ausgabezwischenspeicherung. |
| Anforderungsdekomprimierung | Unterstützt das Dekomprimieren von Anfragen. | All | Vor der Middleware, die den Anfragekörper liest. |
| Antwortkomprimierung | Bietet Unterstützung für das Komprimieren von Antworten. | All | Vor Middleware, die komprimiert werden muss. |
| Lokalisierungsanfrage | Bietet Unterstützung für die Lokalisierung. | All | Vor der Lokalisierung vertraulicher Middleware. Muss nach der Routing-Middleware erscheinen, wenn RouteDataRequestCultureProvider verwendet wird. |
| Zeitüberschreitungen bei Anfragen | Bietet Unterstützung beim Konfigurieren von Anforderungstimeouts, global und pro Endpunkt. | All | UseRequestTimeouts muss nach UseExceptionHandler, UseDeveloperExceptionPage und UseRouting kommen. |
| Endpunkt-Routing. | Definiert Anforderungsrouten und schränkt diese ein. | All | Terminal für entsprechende Routen. |
| Wellness-Spa | Verarbeitet alle Anforderungen ab diesem Punkt in der Middleware-Chain, indem die Standardseite für die Single-Page-Anwendung zurückgegeben wird. | All | Wird spät in der Pipeline angezeigt, sodass andere Middleware für die Bereitstellung statischer Dateien, z. B. MVC-Aktionen, Vorrang hat. |
| Sitzung | Bietet Unterstützung für das Verwalten von Benutzersitzungen. | RP/MVC | Vor Middleware, die eine Session erfordern. |
| Statische Datei | Bietet Unterstützung für das Verarbeiten statischer Dateien und das Durchsuchen des Verzeichnisses. | All | Abschließend, wenn eine Anforderung mit einer Datei übereinstimmt. |
| Umschreiben einer URL | Bietet Unterstützung für das Umschreiben von URLs und das Umleiten von Anforderungen. | All | Vor der Middleware, die die URL verarbeitet. |
| W3C-Protokollierung | Hiermit werden Serverzugriffsprotokolle im erweiterten W3C-Protokolldateiformat generiert. | All | Am Anfang der Middleware-Pipeline. |
| Blazor WebAssembly Debuggen | Debuggt Blazor Web Apps, die clientseitiges Rendern (CSR) in den Chromium-Entwicklertools verwenden. | BWA | Am Anfang der Middleware-Pipeline. |
| WebSockets | Aktiviert das WebSockets-Protokoll. | All | Vor Middleware, die WebSocket-Anfragen annehmen muss. |
Zusätzliche Ressourcen
- Optionen für Lebensdauer und Registrierung (einschließlich Middleware-Beispiel)
- Benutzerdefinierte ASP.NET Core-Middleware schreiben
- Testen von ASP.NET Core-Middleware
- Konfigurieren von gRPC-Web in ASP.NET Core
- Migrieren von HTTP-Modulen zu ASP.NET Core Middleware
- Anwendungsstart in ASP.NET Core
- Anfragefunktionen in ASP.NET Core
- Factorybezogene Middlewareaktivierung in ASP.NET Core
- Middlewareaktivierung mit einem Drittanbietercontainer in ASP.NET Core
- ÜBERSICHT ÜBER APIs