ASP.NET Core Web API-Ausnahmebehandlung

280

Ich verwende ASP.NET Core für mein neues REST-API-Projekt, nachdem ich viele Jahre lang die reguläre ASP.NET-Web-API verwendet habe. Ich sehe keine gute Möglichkeit, Ausnahmen in der ASP.NET Core-Web-API zu behandeln. Ich habe versucht, Ausnahmebehandlungsfilter / -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 Registrierung für den Startfilter:

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 auftritt, AuthorizationFilterdiese nicht von behandelt wird ErrorHandlingFilter. Ich hatte erwartet, dass es dort abgefangen wird, genau wie es mit der alten ASP.NET-Web-API funktioniert.

Wie kann ich also alle Anwendungsausnahmen sowie Ausnahmen von Aktionsfiltern abfangen?

Andrei
quelle
3
Haben Sie UseExceptionHandlerMiddleware ausprobiert ?
Pawel
Ich habe ein Beispiel hier über die Verwendung von UseExceptionHandlerMiddleware
Ilya Chernomordik

Antworten:

537

Ausnahmebehandlung Middleware

Nach vielen Experimenten mit verschiedenen Ausnahmehandlungsansätzen habe ich Middleware verwendet. Für meine ASP.NET Core Web API-Anwendung hat es am besten funktioniert. Es behandelt Anwendungsausnahmen sowie Ausnahmen von Aktionsfiltern und ich habe die volle Kontrolle über die Ausnahmebehandlung und die HTTP-Antwort. Hier ist meine Ausnahmebehandlung für Middleware:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        var code = HttpStatusCode.InternalServerError; // 500 if unexpected

        if      (ex is MyNotFoundException)     code = HttpStatusCode.NotFound;
        else if (ex is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
        else if (ex is MyException)             code = HttpStatusCode.BadRequest;

        var result = JsonConvert.SerializeObject(new { error = ex.Message });
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)code;
        return context.Response.WriteAsync(result);
    }
}

Registrieren Sie es vor MVC in der StartupKlasse:

app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.UseMvc();

Sie können Stack-Trace, Namen des Ausnahmetyps, Fehlercodes oder alles, was Sie möchten, hinzufügen. Sehr flexibel. Hier ist ein Beispiel für eine Ausnahmeantwort:

{ "error": "Authentication token is not valid." }

Erwägen Sie IOptions<MvcJsonOptions>, die InvokeMethode zu injizieren , um sie dann zu verwenden, wenn Sie das Antwortobjekt serialisieren, um die Serialisierungseinstellungen von ASP.NET MVC JsonConvert.SerializeObject(errorObj, opts.Value.SerializerSettings)für eine bessere Serialisierungskonsistenz über alle Endpunkte hinweg zu verwenden.

Ansatz 2

Es gibt eine andere nicht offensichtliche API namens UseExceptionHandler"ok" für einfache Szenarien:

app.UseExceptionHandler(a => a.Run(async context =>
{
    var feature = context.Features.Get<IExceptionHandlerPathFeature>();
    var exception = feature.Error;

    var result = JsonConvert.SerializeObject(new { error = exception.Message });
    context.Response.ContentType = "application/json";
    await context.Response.WriteAsync(result);
}));

Dies ist keine sehr offensichtliche, aber einfache Möglichkeit, die Ausnahmebehandlung einzurichten. Ich bevorzuge jedoch immer noch den Middleware-Ansatz, da ich mehr Kontrolle über die Möglichkeit habe, die erforderlichen Abhängigkeiten einzufügen.

Andrei
quelle
4
Ich habe meinen Kopf gegen den Schreibtisch geschlagen und versucht, eine benutzerdefinierte Middleware zum Laufen zu bringen, und sie funktioniert im Grunde genauso (ich verwende sie, um die Arbeitseinheit / Transaktion für eine Anfrage zu verwalten). Das Problem, mit dem ich konfrontiert bin, ist, dass erhöhte Ausnahmen in "next" nicht in der Middleware abgefangen werden. Wie Sie sich vorstellen können, ist dies problematisch. Was mache ich falsch / fehlt? Irgendwelche Hinweise oder Vorschläge?
Brappleye3
5
@ brappleye3 - Ich habe herausgefunden, was das Problem war. Ich habe gerade die Middleware an der falschen Stelle in der Startup.cs-Klasse registriert. Ich bin app.UseMiddleware<ErrorHandlingMiddleware>();kurz zuvor umgezogen app.UseStaticFiles();. Die Ausnahme scheint jetzt richtig abgefangen zu sein. Dies lässt mich glauben, dass app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); app.UseBrowserLink();Sie einige interne magische Middleware-Hackerarbeiten durchführen müssen, um die Middleware-Bestellung richtig zu machen.
Jamadan
4
Ich bin damit einverstanden, dass benutzerdefinierte Middleware sehr nützlich sein kann, würde jedoch die Verwendung von Ausnahmen für NotFound-, Unauthorized- und BadRequest-Situationen in Frage stellen. Warum nicht einfach den Statuscode festlegen (mit NotFound () usw.) und ihn dann in Ihrer benutzerdefinierten Middleware oder über UseStatusCodePagesWithReExecute verarbeiten? Siehe devtrends.co.uk/blog/handling-errors-in-asp.net-core-web-api für weitere Informationen
Paul Hiles
4
Es ist schlecht, weil es immer in JSON serialisiert wird und die Aushandlung von Inhalten völlig ignoriert.
Konrad
5
@Konrad gültiger Punkt. Deshalb habe ich gesagt, dass Sie in diesem Beispiel loslegen können und nicht das Endergebnis. Für 99% der APIs ist JSON mehr als genug. Wenn Sie der Meinung sind, dass diese Antwort nicht gut genug ist, können Sie gerne einen Beitrag leisten.
Andrei
60

Neueste Asp.Net Core(mindestens ab 2.2, wahrscheinlich früher) verfügt über eine integrierte Middleware, die es im Vergleich zur Implementierung in der akzeptierten Antwort etwas einfacher macht:

app.UseExceptionHandler(a => a.Run(async context =>
{
    var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
    var exception = exceptionHandlerPathFeature.Error;

    var result = JsonConvert.SerializeObject(new { error = exception.Message });
    context.Response.ContentType = "application/json";
    await context.Response.WriteAsync(result);
}));

Es sollte ziemlich genau das Gleiche tun, nur ein bisschen weniger Code zum Schreiben.

Wichtig: Denken Sie daran, es vorher UseMvc(oder UseRoutingin .Net Core 3) hinzuzufügen, da die Reihenfolge wichtig ist.

Ilya Chernomordik
quelle
Unterstützt es DI als Argument für den Handler oder müsste ein Service Locator-Muster innerhalb des Handlers verwendet werden?
lp
31

Am besten verwenden Sie Middleware, um die gewünschte Protokollierung zu erreichen. Sie möchten Ihre Ausnahmeprotokollierung in einer Middleware ablegen und dann Ihre Fehlerseiten behandeln, die dem Benutzer in einer anderen Middleware angezeigt werden. Dies ermöglicht eine Trennung der Logik und folgt dem Design, das Microsoft mit den beiden Middleware-Komponenten festgelegt hat. Hier ist ein guter Link zur Dokumentation von Microsoft: Fehlerbehandlung in ASP.Net Core

Für Ihr spezielles Beispiel möchten Sie möglicherweise eine der Erweiterungen in der StatusCodePage-Middleware verwenden oder Ihre eigene auf diese Weise rollen .

Ein Beispiel für die Protokollierung von Ausnahmen finden Sie hier: ExceptionHandlerMiddleware.cs

public void Configure(IApplicationBuilder app)
{
    // app.UseErrorPage(ErrorPageOptions.ShowAll);
    // app.UseStatusCodePages();
    // app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain"));
    // app.UseStatusCodePages("text/plain", "Response, status code: {0}");
    // app.UseStatusCodePagesWithRedirects("~/errors/{0}");
    // app.UseStatusCodePagesWithRedirects("/base/errors/{0}");
    // app.UseStatusCodePages(builder => builder.UseWelcomePage());
    app.UseStatusCodePagesWithReExecute("/Errors/{0}");  // I use this version

    // Exception handling logging below
    app.UseExceptionHandler();
}

Wenn Ihnen diese spezielle Implementierung nicht gefällt, können Sie auch ELM Middleware verwenden . Hier einige Beispiele: Elm Exception Middleware

public void Configure(IApplicationBuilder app)
{
    app.UseStatusCodePagesWithReExecute("/Errors/{0}");
    // Exception handling logging below
    app.UseElmCapture();
    app.UseElmPage();
}

Wenn dies für Ihre Anforderungen nicht funktioniert, können Sie jederzeit Ihre eigene Middleware-Komponente rollen, indem Sie sich deren Implementierungen der ExceptionHandlerMiddleware und der ElmMiddleware ansehen, um die Konzepte zum Erstellen Ihrer eigenen zu verstehen.

Es ist wichtig, die Ausnahmebehandlungs-Middleware unterhalb der StatusCodePages-Middleware, aber vor allem Ihrer anderen Middleware-Komponenten hinzuzufügen. Auf diese Weise erfasst Ihre Exception-Middleware die Ausnahme, protokolliert sie und lässt die Anforderung dann zur StatusCodePage-Middleware übergehen, die dem Benutzer die freundliche Fehlerseite anzeigt.

Ashley Lee
quelle
Bitte. Ich habe auch einen Link zu einem Beispiel zum Überschreiben der Standard-UseStatusPages für Randfälle bereitgestellt, die Ihre Anforderung möglicherweise besser erfüllen.
Ashley Lee
1
Beachten Sie, dass Elm die Protokolle nicht beibehält und es empfohlen wird, Serilog oder NLog zu verwenden, um die Serialisierung bereitzustellen. Siehe ELM-Protokolle verschwinden. Können wir es in einer Datei oder DB beibehalten?
Michael Freidgeim
2
Die Verbindung ist jetzt unterbrochen.
Mathias Lykkegaard Lorenzen
@AshleyLee, ich frage, dass dies UseStatusCodePagesbei der Implementierung von Web-API-Diensten von Nutzen ist. Keine Ansichten oder HTML überhaupt, nur JSON-Antworten ...
Paul Michalik
23

Eine gut akzeptierte Antwort hat mir sehr geholfen, aber ich wollte HttpStatusCode in meiner Middleware übergeben, um den Fehlerstatuscode zur Laufzeit zu verwalten.

Laut diesem Link habe ich eine Idee, dasselbe zu tun. Also habe ich die Andrei-Antwort damit zusammengeführt. Mein endgültiger Code ist also unten:
1. Basisklasse

public class ErrorDetails
{
    public int StatusCode { get; set; }
    public string Message { get; set; }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}

2. Benutzerdefinierter Ausnahmeklassentyp

 public class HttpStatusCodeException : Exception
{
    public HttpStatusCode StatusCode { get; set; }
    public string ContentType { get; set; } = @"text/plain";

    public HttpStatusCodeException(HttpStatusCode statusCode)
    {
        this.StatusCode = statusCode;
    }

    public HttpStatusCodeException(HttpStatusCode statusCode, string message) : base(message)
    {
        this.StatusCode = statusCode;
    }

    public HttpStatusCodeException(HttpStatusCode statusCode, Exception inner) : this(statusCode, inner.ToString()) { }

    public HttpStatusCodeException(HttpStatusCode statusCode, JObject errorObject) : this(statusCode, errorObject.ToString())
    {
        this.ContentType = @"application/json";
    }

}


3. Benutzerdefinierte Ausnahme Middleware

public class CustomExceptionMiddleware
    {
        private readonly RequestDelegate next;

    public CustomExceptionMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await next(context);
        }
        catch (HttpStatusCodeException ex)
        {
            await HandleExceptionAsync(context, ex);
        }
        catch (Exception exceptionObj)
        {
            await HandleExceptionAsync(context, exceptionObj);
        }
    }

    private Task HandleExceptionAsync(HttpContext context, HttpStatusCodeException exception)
    {
        string result = null;
        context.Response.ContentType = "application/json";
        if (exception is HttpStatusCodeException)
        {
            result = new ErrorDetails() { Message = exception.Message, StatusCode = (int)exception.StatusCode }.ToString();
            context.Response.StatusCode = (int)exception.StatusCode;
        }
        else
        {
            result = new ErrorDetails() { Message = "Runtime Error", StatusCode = (int)HttpStatusCode.BadRequest }.ToString();
            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }
        return context.Response.WriteAsync(result);
    }

    private Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        string result = new ErrorDetails() { Message = exception.Message, StatusCode = (int)HttpStatusCode.InternalServerError }.ToString();
        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return context.Response.WriteAsync(result);
    }
}


4. Verlängerungsmethode

public static void ConfigureCustomExceptionMiddleware(this IApplicationBuilder app)
    {
        app.UseMiddleware<CustomExceptionMiddleware>();
    }

5. Konfigurieren Sie die Methode in startup.cs

app.ConfigureCustomExceptionMiddleware();
app.UseMvc();

Nun meine Anmeldemethode im Account Controller:

 try
        {
            IRepository<UserMaster> obj = new Repository<UserMaster>(_objHeaderCapture, Constants.Tables.UserMaster);
            var Result = obj.Get().AsQueryable().Where(sb => sb.EmailId.ToLower() == objData.UserName.ToLower() && sb.Password == objData.Password.ToEncrypt() && sb.Status == (int)StatusType.Active).FirstOrDefault();
            if (Result != null)//User Found
                return Result;
            else// Not Found
                throw new HttpStatusCodeException(HttpStatusCode.NotFound, "Please check username or password");
        }
        catch (Exception ex)
        {
            throw ex;
        }

Oben können Sie sehen, ob ich den Benutzer nicht gefunden habe, und dann die HttpStatusCodeException auslösen, in der ich den Status HttpStatusCode.NotFound und eine benutzerdefinierte Nachricht
in Middleware übergeben habe

catch (HttpStatusCodeException ex)

blockiert wird aufgerufen, wodurch die Kontrolle an übergeben wird

private Task HandleExceptionAsync-Methode (HttpContext-Kontext, HttpStatusCodeException-Ausnahme)

.


Aber was ist, wenn ich vorher einen Laufzeitfehler habe? Dafür habe ich try catch block verwendet, der eine Ausnahme auslöst und im catch-Block (Exception exceptionObj) abgefangen wird und die Kontrolle an übergibt

Task HandleExceptionAsync (HttpContext-Kontext, Ausnahme Ausnahme)

Methode.

Ich habe eine einzelne ErrorDetails-Klasse verwendet, um die Einheitlichkeit zu gewährleisten.

Arjun
quelle
Wo soll die Erweiterungsmethode platziert werden? Leider bekomme ich im startup.csin void Configure(IapplicationBuilder app)einen Fehler IApplicationBuilder does not contain a definition for ConfigureCustomExceptionMiddleware. Und ich habe die Referenz hinzugefügt, wo CustomExceptionMiddleware.csist.
Spedo De La Rossa
Sie möchten keine Ausnahmen verwenden, da diese Ihre Apis verlangsamen. Ausnahmen sind sehr teuer.
lnaie
@Inaie, kann ich nicht dazu sagen ... aber es scheint, dass Sie nie eine Ausnahme haben, um damit
Arjun
19

Um das Verhalten bei der Ausnahmebehandlung pro Ausnahmetyp zu konfigurieren, können Sie Middleware aus NuGet-Paketen verwenden:

Codebeispiel:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddExceptionHandlingPolicies(options =>
    {
        options.For<InitializationException>().Rethrow();

        options.For<SomeTransientException>().Retry(ro => ro.MaxRetryCount = 2).NextPolicy();

        options.For<SomeBadRequestException>()
        .Response(e => 400)
            .Headers((h, e) => h["X-MyCustomHeader"] = e.Message)
            .WithBody((req,sw, exception) =>
                {
                    byte[] array = Encoding.UTF8.GetBytes(exception.ToString());
                    return sw.WriteAsync(array, 0, array.Length);
                })
        .NextPolicy();

        // Ensure that all exception types are handled by adding handler for generic exception at the end.
        options.For<Exception>()
        .Log(lo =>
            {
                lo.EventIdFactory = (c, e) => new EventId(123, "UnhandlerException");
                lo.Category = (context, exception) => "MyCategory";
            })
        .Response(null, ResponseAlreadyStartedBehaviour.GoToNextHandler)
            .ClearCacheHeaders()
            .WithObjectResult((r, e) => new { msg = e.Message, path = r.Path })
        .Handled();
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseExceptionHandlingPolicies();
    app.UseMvc();
}
Ihar Yakimush
quelle
16

Erstens danke ich Andrei, der meine Lösung auf sein Beispiel gestützt hat.

Ich schließe meine ein, da es sich um ein vollständigeres Beispiel handelt und den Lesern möglicherweise Zeit spart.

Die Einschränkung des Ansatzes von Andrei besteht darin, dass die Protokollierung, die Erfassung potenziell nützlicher Anforderungsvariablen und die Aushandlung von Inhalten nicht behandelt werden (JSON wird immer zurückgegeben, unabhängig davon, was der Client angefordert hat - XML ​​/ Nur-Text usw.).

Mein Ansatz ist die Verwendung eines ObjectResult, mit dem wir die in MVC integrierte Funktionalität verwenden können.

Dieser Code verhindert auch das Zwischenspeichern der Antwort.

Die Fehlerantwort wurde so dekoriert, dass sie vom XML-Serializer serialisiert werden kann.

public class ExceptionHandlerMiddleware
{
    private readonly RequestDelegate next;
    private readonly IActionResultExecutor<ObjectResult> executor;
    private readonly ILogger logger;
    private static readonly ActionDescriptor EmptyActionDescriptor = new ActionDescriptor();

    public ExceptionHandlerMiddleware(RequestDelegate next, IActionResultExecutor<ObjectResult> executor, ILoggerFactory loggerFactory)
    {
        this.next = next;
        this.executor = executor;
        logger = loggerFactory.CreateLogger<ExceptionHandlerMiddleware>();
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, $"An unhandled exception has occurred while executing the request. Url: {context.Request.GetDisplayUrl()}. Request Data: " + GetRequestData(context));

            if (context.Response.HasStarted)
            {
                throw;
            }

            var routeData = context.GetRouteData() ?? new RouteData();

            ClearCacheHeaders(context.Response);

            var actionContext = new ActionContext(context, routeData, EmptyActionDescriptor);

            var result = new ObjectResult(new ErrorResponse("Error processing request. Server error."))
            {
                StatusCode = (int) HttpStatusCode.InternalServerError,
            };

            await executor.ExecuteAsync(actionContext, result);
        }
    }

    private static string GetRequestData(HttpContext context)
    {
        var sb = new StringBuilder();

        if (context.Request.HasFormContentType && context.Request.Form.Any())
        {
            sb.Append("Form variables:");
            foreach (var x in context.Request.Form)
            {
                sb.AppendFormat("Key={0}, Value={1}<br/>", x.Key, x.Value);
            }
        }

        sb.AppendLine("Method: " + context.Request.Method);

        return sb.ToString();
    }

    private static void ClearCacheHeaders(HttpResponse response)
    {
        response.Headers[HeaderNames.CacheControl] = "no-cache";
        response.Headers[HeaderNames.Pragma] = "no-cache";
        response.Headers[HeaderNames.Expires] = "-1";
        response.Headers.Remove(HeaderNames.ETag);
    }

    [DataContract(Name= "ErrorResponse")]
    public class ErrorResponse
    {
        [DataMember(Name = "Message")]
        public string Message { get; set; }

        public ErrorResponse(string message)
        {
            Message = message;
        }
    }
}
CountZero
quelle
9

Konfigurieren Sie zunächst ASP.NET Core 2 so Startup, dass es bei Fehlern vom Webserver und nicht behandelten Ausnahmen erneut auf einer Fehlerseite ausgeführt wird.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment()) {
        // Debug config here...
    } else {
        app.UseStatusCodePagesWithReExecute("/Error");
        app.UseExceptionHandler("/Error");
    }
    // More config...
}

Definieren Sie als Nächstes einen Ausnahmetyp, mit dem Sie Fehler mit HTTP-Statuscodes auslösen können.

public class HttpException : Exception
{
    public HttpException(HttpStatusCode statusCode) { StatusCode = statusCode; }
    public HttpStatusCode StatusCode { get; private set; }
}

Passen Sie schließlich in Ihrem Controller für die Fehlerseite die Antwort basierend auf dem Grund für den Fehler und der Frage an, ob die Antwort direkt von einem Endbenutzer angezeigt wird. Dieser Code setzt voraus, dass alle API-URLs mit beginnen /api/.

[AllowAnonymous]
public IActionResult Error()
{
    // Gets the status code from the exception or web server.
    var statusCode = HttpContext.Features.Get<IExceptionHandlerFeature>()?.Error is HttpException httpEx ?
        httpEx.StatusCode : (HttpStatusCode)Response.StatusCode;

    // For API errors, responds with just the status code (no page).
    if (HttpContext.Features.Get<IHttpRequestFeature>().RawTarget.StartsWith("/api/", StringComparison.Ordinal))
        return StatusCode((int)statusCode);

    // Creates a view model for a user-friendly error page.
    string text = null;
    switch (statusCode) {
        case HttpStatusCode.NotFound: text = "Page not found."; break;
        // Add more as desired.
    }
    return View("Error", new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier, ErrorText = text });
}

ASP.NET Core protokolliert die Fehlerdetails, mit denen Sie debuggen können, sodass Sie möglicherweise nur einen Statuscode für einen (möglicherweise nicht vertrauenswürdigen) Anforderer bereitstellen möchten. Wenn Sie weitere Informationen anzeigen möchten, können Sie diese erweitern HttpException, um sie bereitzustellen. Für API - Fehler, können Sie setzen JSON-kodierte Fehlerinformationen in dem Nachrichtentext durch den Ersatz return StatusCode...mit return Json....

Edward Brey
quelle
0

Verwenden Sie Middleware oder IExceptionHandlerPathFeature ist in Ordnung. Es gibt einen anderen Weg im Eshop

Erstellen Sie einen Ausnahmefilter und registrieren Sie ihn

public class HttpGlobalExceptionFilter : IExceptionFilter
{
  public void OnException(ExceptionContext context)
  {...}
}
services.AddMvc(options =>
{
  options.Filters.Add(typeof(HttpGlobalExceptionFilter));
})
ws_
quelle