In ASP.NET Core bezieht sich Middleware auf Softwarekomponenten, die HTTP-Anforderungen in einer ASP.NET Core-Anwendung verarbeiten. Diese Middleware wird in einer Pipeline organisiert, die den HTTP-Request-Response-Lebenszyklus steuert.
ASP.NET Core Middleware kann verschiedene Aufgaben erfüllen, wie z.B. Authentifizierung, Autorisierung, Routing, Fehlerbehandlung, Protokollierung und mehr. Sie werden verwendet, um die Funktionalität einer Anwendung zu erweitern oder anzupassen, ohne Änderungen am Hauptcode vornehmen zu müssen.
Eine Middleware-Komponente in ASP.NET Core besteht aus einer Methode, die einen RequestDelegate als Parameter annimmt und einen Task zurückgibt. Der RequestDelegate repräsentiert den nächsten Schritt in der Pipeline, den die Middleware aufruft, nachdem sie ihre Aufgabe erfüllt hat.
Eine Middleware durch ein Request Delegaten hinzufügen.
Mit der Use Methode an der WebApplication Instanz kann man eine Middleware hinzufügen. Man übergibt eine lambda Methode mit zwei Argumenten. Das erste Argument ist ein HttpContext und das zweite Argument ist der aktuelle RequestDelegate.
So sollte die Registrierung aussehen:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Use(async (context, next) =>
{
// Vorverarbeitung
// Beispiel: Protokollierung von Request-Informationen
// Aufruf des nächsten Schritts in der Pipeline
await next(context);
// Nachverarbeitung
// Beispiel: Protokollierung von Response-Informationen
});
Eine Middleware durch die Methoden Konvention hinzufügen
Beim zweitem Weg brauchen wir eine Klasse die sich an bestimmte Konventionen hält damit man diese als Middleware registrieren kann.
Die Konventionen die diese Klasse einhalten muss sind folgende:
- Ein Konstruktor mit einem
RequestDelegateParameter - Eine Methode
InvokeAsyncdie denHttpContextals Parameter enthält. - Der
RequestDelegatemuss mit demHttpContextaufgerufen werden.
So sollte die Klasse aussehen:
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// Vorverarbeitung
// Beispiel: Protokollierung von Request-Informationen
// Aufruf des nächsten Schritts in der Pipeline
await _next(context);
// Nachverarbeitung
// Beispiel: Protokollierung von Response-Informationen
}
}
Die Middleware muss dann noch an der Applikation Registriert werden.
app.UseMiddleware<CustomMiddleware>();
Eine Middleware mit dem Interface IMiddleware hinzufügen
Im drittem Beispiel fügen wir auch eine neue Klasse hinzu, die unsere Middleware ist. Diesmal implementieren wir das interface IMiddleware. Dieses Interface hat eine Methode InvokeAsync
public class CustomMiddleware : IMiddleware
{
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
// Vorverarbeitung
// Beispiel: Protokollierung von Request-Informationen
// Aufruf des nächsten Schritts in der Pipeline
await next(context);
// Nachverarbeitung
// Beispiel: Protokollierung von Response-Informationen
}
}
Da die Middleware in diesem Fall von der Dependency Injection erzeugt wird, müssen wir diese erst registrieren.
builder.Services.AddTransient<CustomMiddleware>();
Und dann die Middleware noch an der Applikation registrieren.
app.UseMiddleware<CustomMiddleware>();
Meine Empfehlung welcher Weg der beste ist:
Ich bin ein großer Fan von Typisierten Programmieren, wann immer es möglich ist. Von den drei Ansätzen, die ich gerade gezeigt habe, ist die Implementierung mit dem IMiddleware Interface für mich am besten. Da wir mit einem Interface arbeiten, ist es sehr einfach eine Erweiterung zu schreiben, die beim Start alle Klassen die das IMiddleware Interface Implementieren findet und somit diese automatisch Registriert.