ASP.NET Core Web API-Ausnahmebehandlung
Ich begann mit ASP.NET Core für mein neues REST-API-Projekt nach der Verwendung von regelmäßigen ASP.NET Web API für viele Jahre. Ich sehe keinen guten Weg, um Ausnahmen in ASP.NET Core Web API zu behandeln. Ich habe versucht, Ausnahmebehandlung Filter/Attribut zu implementieren:
public class ErrorHandlingFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
HandleExceptionAsync(context);
context.ExceptionHandled = true;
}
private static void HandleExceptionAsync(ExceptionContext context)
{
var exception = context.Exception;
if (exception is MyNotFoundException)
SetExceptionResult(context, exception, HttpStatusCode.NotFound);
else if (exception is MyUnauthorizedException)
SetExceptionResult(context, exception, HttpStatusCode.Unauthorized);
else if (exception is MyException)
SetExceptionResult(context, exception, HttpStatusCode.BadRequest);
else
SetExceptionResult(context, exception, HttpStatusCode.InternalServerError);
}
private static void SetExceptionResult(
ExceptionContext context,
Exception exception,
HttpStatusCode code)
{
context.Result = new JsonResult(new ApiResponse(exception))
{
StatusCode = (int)code
};
}
}
Und hier ist meine Startup-Filter-Registrierung:
services.AddMvc(options =>
{
options.Filters.Add(new AuthorizationFilter());
options.Filters.Add(new ErrorHandlingFilter());
});
Das Problem, das ich hatte, ist, dass wenn eine Ausnahme in meinem AuthorizationFilter
auftritt, diese nicht von ErrorHandlingFilter
behandelt wird. Ich hatte erwartet, dass es dort abgefangen wird, so wie es bei der alten ASP.NET Web API funktioniert hat.
Wie kann ich also alle Anwendungsausnahmen sowie alle Ausnahmen von Aktionsfiltern abfangen?
230
3
Middleware für die Behandlung von Ausnahmen
Nach vielen Experimenten mit verschiedenen Ansätzen zur Ausnahmebehandlung habe ich mich für Middleware entschieden. Sie hat sich für meine ASP.NET Core Web API-Anwendung am besten bewährt. Sie behandelt sowohl Anwendungsausnahmen als auch Ausnahmen von Aktionsfiltern und ich habe die volle Kontrolle über die Ausnahmebehandlung und die HTTP-Antwort. Hier ist meine Middleware für die Ausnahmebehandlung:
Registrieren Sie sie vor MVC in der Klasse
Startup
:Sie können Stack-Trace, Ausnahmetyp-Namen, Fehlercodes oder was immer Sie wollen, hinzufügen. Sehr flexibel. Hier ist ein Beispiel für eine Ausnahmeantwort:
Ziehen Sie in Erwägung,
IOptions
in dieInvoke
-Methode zu injizieren, um es dann zu verwenden, wenn Sie das Antwortobjekt serialisieren, um die Serialisierungseinstellungen von ASP.NET MVC'inJsonConvert.SerializeObject(errorObj, opts.Value.SerializerSettings)
für eine bessere Serialisierungskonsistenz über alle Endpunkte hinweg zu nutzen.Ansatz 2
Es gibt eine weitere nicht offensichtliche API namens "UseExceptionHandler", die für einfache Szenarien funktioniert:
Dies ist ein nicht sehr offensichtlicher, aber einfacher Weg, die Ausnahmebehandlung einzurichten. Ich bevorzuge jedoch immer noch den Middleware-Ansatz, da ich mehr Kontrolle über die Möglichkeit habe, notwendige Abhängigkeiten zu injizieren.
Am besten verwenden Sie Middleware, um die von Ihnen gewünschte Protokollierung zu erreichen. Sie möchten Ihre Ausnahmeprotokollierung in einer Middleware unterbringen und dann Ihre Fehlerseiten, die dem Benutzer angezeigt werden, in einer anderen Middleware behandeln. Das ermöglicht die Trennung der Logik und folgt dem Design, das Microsoft mit den 2 Middleware-Komponenten festgelegt hat. Hier ist ein guter Link zur Dokumentation von Microsoft: Fehlerbehandlung in ASP.Net Core
Für Ihr spezielles Beispiel können Sie eine der Erweiterungen in der StatusCodePage-Middleware verwenden oder Ihre eigene wie diese entwickeln.
Ein Beispiel für die Protokollierung von Ausnahmen finden Sie hier: ExceptionHandlerMiddleware.cs
Wenn Sie diese spezielle Implementierung nicht mögen, können Sie auch ELM Middleware verwenden, und hier sind einige Beispiele: Elm Exception Middleware
Wenn das für Ihre Bedürfnisse nicht funktioniert, können Sie jederzeit Ihre eigene Middleware-Komponente entwickeln, indem Sie sich die Implementierungen der ExceptionHandlerMiddleware und der ElmMiddleware ansehen, um die Konzepte für die Erstellung Ihrer eigenen Middleware zu verstehen.
Es ist wichtig, die Middleware für die Ausnahmebehandlung unterhalb der StatusCodePages-Middleware, aber oberhalb aller anderen Middleware-Komponenten einzufügen. Auf diese Weise wird Ihre Exception-Middleware die Ausnahme erfassen, protokollieren und dann die Anfrage an die StatusCodePage-Middleware weiterleiten, die dem Benutzer die freundliche Fehlerseite anzeigt.
Konfigurieren Sie zunächst ASP.NET Core 2
Startup
so, dass bei Fehlern vom Webserver und unbehandelten Ausnahmen erneut eine Fehlerseite aufgerufen wird.Als nächstes definieren Sie einen Ausnahmetyp, mit dem Sie Fehler mit HTTP-Statuscodes auslösen können.
Schließlich passen Sie in Ihrem Controller für die Fehlerseite die Antwort auf der Grundlage der Fehlerursache und der Tatsache an, ob die Antwort direkt von einem Endbenutzer gesehen wird. Dieser Code geht davon aus, dass alle API-URLs mit "/api/" beginnen.
ASP.NET Core protokolliert die Fehlerdetails, damit Sie sie debuggen können. Daher ist ein Statuscode möglicherweise alles, was Sie einem (potenziell nicht vertrauenswürdigen) Anforderer mitteilen möchten. Wenn Sie mehr Informationen anzeigen möchten, können Sie
HttpException
erweitern, um diese bereitzustellen. Bei API-Fehlern können Sie JSON-kodierte Fehlerinformationen in den Nachrichtentext einfügen, indem Siereturn StatusCode...
durchreturn Json...
ersetzen.