Fehlerbehandlung in ASP.NET Core

Von Kirk Larkin, Tom Dykstra und Steve Smith

Dieser Artikel beschreibt grundsätzliche Vorgehensweisen zur Behandlung von Fehlern in ASP.NET Core-Web-Apps. Weitere Informationen für Web-Apps finden Sie unter Fehlerbehandlung in ASP.NET Core-Web-APIs.

Anzeigen oder Herunterladen von Beispielcode (Informationen zum Herunterladen.) Die Registerkarte „Netzwerk“ in den F12-Entwicklertools im Browser ist beim Testen der Beispiel-App nützlich.

Seite mit Ausnahmen für Entwickler

Die Seite mit Ausnahmen für Entwickler enthält ausführliche Informationen zu unbehandelten Anforderungsausnahmen. Die ASP.NET Core-Vorlagen generieren den folgenden Code:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Der vorangehende hervorgehobene Code aktiviert die Seite mit Ausnahmen für Entwickler, wenn die App in der Entwicklungsumgebung ausgeführt wird.

Die Vorlagen platzieren UseDeveloperExceptionPage am Anfang der Middlewarepipeline, sodass die in der nachfolgenden Middleware ausgelösten unbehandelten Ausnahmen abgefangen werden.

Der vorangehende Code aktiviert die Seite mit Ausnahmen für Entwickler nur dann, wenn die App in der Entwicklungsumgebung ausgeführt wird. Bei Ausführung der App in der Produktionsumgebung sollten keine detaillierten Informationen zu den Ausnahmen öffentlich angezeigt werden. Weitere Informationen zum Konfigurieren der Umgebungen finden Sie unter Verwenden von mehreren Umgebungen in ASP.NET Core.

Die Seite mit Ausnahmen für Entwickler kann die folgenden Informationen zu der Ausnahme und der Anforderung enthalten:

  • Stapelüberwachung
  • Abfragezeichenfolgeparameter, sofern vorhanden
  • Cookies, sofern vorhanden
  • Header

Es kann nicht gewährleistet werden, dass die Seite mit Ausnahmen für Entwickler alle Informationen enthält. Vollständige Informationen zu Fehlern finden Sie unter Protokollierung.

Seite „Ausnahmehandler“

Um eine benutzerdefinierte Fehlerbehandlungsseite für die Produktionsumgebung zu konfigurieren, rufen Sie UseExceptionHandler auf. Die Aufgaben der Middleware zur Ausnahmebehandlung:

  • Dient zum Abfangen und Protokollieren unbehandelter Ausnahmen.
  • Führt erneut die Anforderung in einer anderen Pipeline im angegebenen Pfad aus. Die Anforderung wird nicht erneut ausgeführt, wenn die Antwort gestartet wurde. Der von der Vorlage generierte Code führt die Anforderung erneut mit dem /Error-Pfad aus.

Warnung

Wenn die alternative Pipeline eigenständig eine Ausnahme auslöst, löst die Middleware für die Ausnahmebehandlung erneut die ursprüngliche Ausnahme aus.

Im folgenden Beispiel fügt UseExceptionHandler die Middleware zur Ausnahmebehandlung in Nichtentwicklungsumgebungen hinzu:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

Die Razor Pages-App-Vorlage stellt im Ordner Pages eine Fehlerseite (.cshtml) und eine PageModel-Klasse (ErrorModel) bereit. Die Projektvorlage für eine MVC-App enthält eine Error-Aktionsmethode und eine Fehleransicht für den Home-Controller.

Die Middleware für die Ausnahmebehandlung führt die Anforderung unter Verwendung der ursprünglichen HTTP-Methode erneut aus. Wenn ein Endpunkt für die Fehlerbehandlung auf bestimmte HTTP-Methoden beschränkt ist, wird er nur für diese Methoden ausgeführt. Beispielsweise wird eine MVC-Controller-Aktion, die das Attribut [HttpGet] verwendet, nur für GET-Anforderungen ausgeführt. Um sicherzustellen, dass alle Anforderungen die benutzerdefinierte Seite für die Fehlerbehandlung erreichen, beschränken Sie die Endpunkte nicht auf bestimmte HTTP-Methoden.

So behandeln Sie Ausnahmen unterschiedlich, basierend auf der ursprünglichen HTTP-Methode:

  • Für Razor Pages erstellen Sie mehrere Handlermethoden. Verwenden Sie beispielsweise OnGet zum Behandeln von GET-Ausnahmen und OnPost zum Behandeln von POST-Ausnahmen.
  • Für MVC wenden Sie HTTP-Verbattribute auf mehrere Aktionen an. Verwenden Sie beispielsweise [HttpGet] zum Behandeln von GET-Ausnahmen und [HttpPost] zum Behandeln von POST-Ausnahmen.

Um nicht authentifizierten Benutzern die Anzeige der benutzerdefinierten Seite für die Fehlerbehandlung zu ermöglichen, stellen Sie sicher, dass der anonyme Zugriff unterstützt wird.

Zugreifen auf die Ausnahme

Verwenden Sie IExceptionHandlerPathFeature, um auf die Ausnahme oder den Pfad der ursprünglichen Anforderung in einem Fehlerhandler zuzugreifen. Der folgende Code fügt dem Standard Pages/Error.cshtml.cs die von den ASP.NET Core-Vorlagen generierte ExceptionMessage hinzu:

[ResponseCache(Duration=0, Location=ResponseCacheLocation.None, NoStore=true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
    public string RequestId { get; set; }
    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
    public string ExceptionMessage { get; set; }
    private readonly ILogger<ErrorModel> _logger;

    public ErrorModel(ILogger<ErrorModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

        var exceptionHandlerPathFeature =
        HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "File error thrown";
            _logger.LogError(ExceptionMessage);
        }
        if (exceptionHandlerPathFeature?.Path == "/index")
        {
            ExceptionMessage += " from home page";
        }
    }
}

Warnung

Stellen Sie Clients keine vertraulichen Fehlerinformationen bereit. Die Bereitstellung von Fehlern ist ein Sicherheitsrisiko.

So testen Sie die Ausnahme in der Beispiel-App

  • Legen Sie die Umgebung auf Produktion fest.
  • Entfernen Sie die Kommentare aus webBuilder.UseStartup<Startup>(); in Program.cs.
  • Wählen Sie Trigger an exception (Ausnahme auslösen) auf der Startseite aus.

Lambda-Ausdruck für Ausnahmehandler

Eine Alternative zu einer benutzerdefinierten Ausnahmebehandlungsseite ist das Angeben eines Lambda-Ausdrucks für UseExceptionHandler. Die Verwendung eines Lambda-Ausdrucks ermöglicht den Zugriff auf den Fehler, bevor die Antwort zurückgegeben wird.

Der folgende Code verwendet einen Lambdaausdruck für die Ausnahmebehandlung:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler(errorApp =>
        {
            errorApp.Run(async context =>
            {
                context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;;
                context.Response.ContentType = "text/html";

                await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
                await context.Response.WriteAsync("ERROR!<br><br>\r\n");

                var exceptionHandlerPathFeature =
                    context.Features.Get<IExceptionHandlerPathFeature>();

                if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
                {
                    await context.Response.WriteAsync(
                                              "File error thrown!<br><br>\r\n");
                }

                await context.Response.WriteAsync(
                                              "<a href=\"/\">Home</a><br>\r\n");
                await context.Response.WriteAsync("</body></html>\r\n");
                await context.Response.WriteAsync(new string(' ', 512)); 
            });
        });
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Warnung

Stellen Sie keine vertraulichen Fehlerinformationen aus IExceptionHandlerFeature oder IExceptionHandlerPathFeature für Clients bereit. Die Bereitstellung von Fehlern ist ein Sicherheitsrisiko.

So testen Sie den Lambdaausdruck für die Ausnahmebehandlung in der Beispiel-App

  • Legen Sie die Umgebung auf Produktion fest.
  • Entfernen Sie die Kommentare aus webBuilder.UseStartup<StartupLambda>(); in Program.cs.
  • Wählen Sie Trigger an exception (Ausnahme auslösen) auf der Startseite aus.

UseStatusCodePages

Die ASP.NET Core-App stellt für HTTP-Fehlerstatuscodes wie 404 – Nicht gefunden standardmäßig keine Statuscodeseite zur Verfügung. Wenn die App einen HTTP-Fehlerstatuscode 400–599 feststellt, der keinen Text enthält, werden der Statuscode und ein leerer Antworttext zurückgegeben. Verwenden Sie zum Bereitstellen von Statuscodeseiten Middleware für Statuscodeseiten. Um für gängige Statuscodes einfache Handler im Textformat zu aktivieren, rufen Sie in der Startup.Configure-Methode UseStatusCodePages auf:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePages();

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Rufen Sie UseStatusCodePages vor der Middleware für die Anforderungsverarbeitung auf. Rufen Sie beispielsweise UseStatusCodePages vor der Middleware für statische Dateien und der Middleware für Endpunkte auf.

Wenn UseStatusCodePages nicht verwendet wird, wird beim Navigieren zu einer URL ohne Endpunkt eine browserabhängige Fehlermeldung zurückgegeben, die angibt, dass der Endpunkt nicht gefunden werden kann. Navigieren Sie zum Beispiel zu Home/Privacy2. Wenn UseStatusCodePages aufgerufen wird, gibt der Browser Folgendes zurück:

Status Code: 404; Not Found

UseStatusCodePages wird normalerweise nicht in der Produktionsumgebung verwendet, da diese Methode eine Meldung zurückgibt, die für Benutzer nicht nützlich ist.

So testen Sie UseStatusCodePages in der Beispiel-App

  • Legen Sie die Umgebung auf Produktion fest.
  • Entfernen Sie die Kommentare aus webBuilder.UseStartup<StartupUseStatusCodePages>(); in Program.cs.
  • Klicken Sie auf die Links auf der Startseite.

Hinweis

Die Middleware für Statuscodeseiten erfasst keine Ausnahmen. Um eine benutzerdefinierte Fehlerbehandlungsseite bereitzustellen, verwenden Sie die Ausnahmehandlerseite.

UseStatusCodePages mit Formatzeichenfolge

Um den Inhaltstyp und Text der Antwort anzupassen, verwenden Sie die Überladung von UseStatusCodePages, die einen Inhaltstyp und eine Formatierungszeichenfolge erfordert:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePages(
        "text/plain", "Status code page, status code: {0}");

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Im vorangehenden Code ist {0} ein Platzhalter für den Fehlercode.

UseStatusCodePages mit Formatzeichenfolge wird normalerweise nicht in der Produktionsumgebung verwendet, da diese Methode eine Meldung zurückgibt, die für Benutzer nicht nützlich ist.

Um UseStatusCodePages in der Beispiel-App zu testen, entfernen Sie die Kommentare aus webBuilder.UseStartup<StartupFormat>(); in Program.cs.

UseStatusCodePages mit Lambda-Ausdruck

Um benutzerdefinierten Code für die Fehlerbehandlung und das Schreiben von Antworten anzugeben, verwenden Sie die Überladung von UseStatusCodePages, die einen Lambda-Ausdruck verwendet:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePages(async context =>
    {
        context.HttpContext.Response.ContentType = "text/plain";

        await context.HttpContext.Response.WriteAsync(
            "Status code page, status code: " +
            context.HttpContext.Response.StatusCode);
    });

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

UseStatusCodePages mit Lambdaausdruck wird normalerweise nicht in der Produktionsumgebung verwendet, da diese Methode eine Meldung zurückgibt, die für Benutzer nicht nützlich ist.

Um UseStatusCodePages in der Beispiel-App zu testen, entfernen Sie die Kommentare aus webBuilder.UseStartup<StartupStatusLambda>(); in Program.cs.

UseStatusCodePagesWithRedirects

Die Erweiterungsmethode UseStatusCodePagesWithRedirects:

  • Sendet den Statuscode 302 Found (Gefunden) an den Client.
  • Leitet den Client an den in der URL-Vorlage angegebenen Fehlerbehandlungsendpunkt weiter. Der Fehlerbehandlungsendpunkt zeigt in der Regel Fehlerinformationen an und gibt den HTTP-Code 200 zurück.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePagesWithRedirects("/MyStatusCode?code={0}");

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Die URL-Vorlage kann, wie im vorangehenden Code gezeigt, einen {0}-Platzhalter für den Statuscode enthalten. Wenn die URL-Vorlage mit einer Tilde (~) beginnt, wird ~ durch die Angabe für PathBase der App ersetzt. Wenn Sie in der App einen Endpunkt angeben, müssen Sie eine MVC-Ansicht oder Razor-Seite für den Endpunkt erstellen. Ein Razor Pages-Beispiel finden Sie unter Pages/MyStatusCode.cshtml in der Beispiel-App.

Diese Methode wird häufig verwendet, wenn die App Folgendes tun soll:

  • Den Client an einen anderen Endpunkt umleiten, in der Regel in Fällen, in denen eine andere App den Fehler verarbeitet. Für Web-Apps gibt die Adressleiste des Browsers des Clients den umgeleiteten Endpunkt wieder.
  • Den ursprünglichen Statuscode mit der anfänglichen Umleitungsantwort nicht beibehalten und zurückgeben.

Um UseStatusCodePages in der Beispiel-App zu testen, entfernen Sie die Kommentare aus webBuilder.UseStartup<StartupSCredirect>(); in Program.cs.

UseStatusCodePagesWithReExecute

Die Erweiterungsmethode UseStatusCodePagesWithReExecute:

  • Gibt den ursprünglichen Statuscode an den Client zurück.
  • Generiert den Antworttext durch die erneute Ausführung der Anforderungspipeline mithilfe eines alternativen Pfads.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStatusCodePagesWithReExecute("/MyStatusCode2", "?code={0}");

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Wenn in der App ein Endpunkt angegeben ist, müssen Sie eine MVC-Ansicht oder Razor-Seite für den Endpunkt erstellen. Stellen Sie sicher, dass UseStatusCodePagesWithReExecute vor UseRouting platziert wird, damit die Anforderung an die Statusseite umgeleitet werden kann. Ein Razor Pages-Beispiel finden Sie unter Pages/MyStatusCode2.cshtml in der Beispiel-App.

Diese Methode wird häufig verwendet, wenn die App Folgendes tun soll:

  • Die Anforderung ohne Umleitung an einen anderen Endpunkt verarbeiten. Für Web-Apps gibt die Adressleiste des Browsers des Clients den ursprünglich angeforderten Endpunkt wieder.
  • Den ursprünglichen Statuscode mit der Antwort beibehalten und zurückgeben.

Die Vorlagen für URL und Abfragezeichenfolgen können für den Statuscode einen Platzhalter ({0}) enthalten. Die URL-Vorlage muss mit einem Schrägstrich (/) beginnen.

Der Endpunkt, der den Fehler verarbeitet, kann die ursprüngliche URL abrufen, die den Fehler generiert hat (siehe folgendes Beispiel):

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class MyStatusCode2Model : PageModel
{
    public string RequestId { get; set; }
    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

    public string ErrorStatusCode { get; set; }

    public string OriginalURL { get; set; }
    public bool ShowOriginalURL => !string.IsNullOrEmpty(OriginalURL);

    public void OnGet(string code)
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        ErrorStatusCode = code;

        var statusCodeReExecuteFeature = HttpContext.Features.Get<
                                               IStatusCodeReExecuteFeature>();
        if (statusCodeReExecuteFeature != null)
        {
            OriginalURL =
                statusCodeReExecuteFeature.OriginalPathBase
                + statusCodeReExecuteFeature.OriginalPath
                + statusCodeReExecuteFeature.OriginalQueryString;
        }
    }
}

Ein Razor Pages-Beispiel finden Sie unter Pages/MyStatusCode2.cshtml in der Beispiel-App.

Um UseStatusCodePages in der Beispiel-App zu testen, entfernen Sie die Kommentare aus webBuilder.UseStartup<StartupSCreX>(); in Program.cs.

Deaktivieren von Statuscodeseiten

Verwenden Sie das Attribut [SkipStatusCodePages], um Statuscodeseiten für einen MVC-Controller oder eine MVC-Aktionsmethode zu deaktivieren.

Verwenden Sie IStatusCodePagesFeature, um Statuscodeseiten für bestimmte Anforderungen in der Handlermethode von Razor Pages oder in einem MVC-Controller zu deaktivieren:

public void OnGet()
{
    // using Microsoft.AspNetCore.Diagnostics;
    var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();

    if (statusCodePagesFeature != null)
    {
        statusCodePagesFeature.Enabled = false;
    }
}

Ausnahmebehandlungscode

Code auf Seiten zur Ausnahmebehandlung kann ebenfalls Ausnahmen auslösen. Produktionsfehlerseiten sollten gründlich getestet werden. Achten Sie darauf, dabei keine eigenen Ausnahmen auszulösen.

Antwortheader

Nachdem die Header für eine Antwort gesendet wurden:

  • Die App kann den Statuscode der Antwort nicht ändern.
  • Weder Ausnahmeseiten noch Handler können ausgeführt werden. Die Antwort muss abgeschlossen oder die Verbindung unterbrochen werden.

Sichere Ausnahmebehandlung

Neben der Ausnahmebehandlungslogik in einer App kann die HTTP-Serverimplementierung einige Ausnahmebehandlungen durchführen. Wenn der Server eine Ausnahme erfasst, bevor die Antwortheader gesendet werden, sendet der Server die Antwort 500 - Internal Server Error ohne Antworttext. Wenn der Server eine Ausnahme auffängt, nachdem die Antwortheader gesendet wurden, schließt der Server die Verbindung. Anforderungen, die nicht von der App verarbeitet werden, werden vom Server verarbeitet. Jede Ausnahme, die bei der Anforderungsverarbeitung durch den Server auftritt, wird durch die Ausnahmebehandlung des Servers verarbeitet. Die benutzerdefinierten Fehlerseiten der App, Middleware zur Fehlerbehandlung und Filter haben keine Auswirkungen auf dieses Verhalten.

Fehlerbehandlung während des Starts

Nur auf Hostebene können Ausnahmen behandelt werden, die während des Starts einer App auftreten. Der Host kann für das Erfassen von Startfehlern und Erfassen detaillierter Fehler konfiguriert werden.

Die Hostingebene kann nur dann für einen beim Start erfassten Fehler eine Fehlerseite anzeigen, wenn der Fehler nach der Bindung an die Hostadresse bzw. den Port auftritt. Wenn die Bindung misslingt:

  • Die Hostebene protokolliert eine kritische Ausnahme.
  • Der DotNet-Prozess stürzt ab.
  • Wenn der HTTP-Server Kestrel heißt, wird keine Fehlerseite angezeigt.

Wenn sie auf IIS (oder Azure App Service) oder IIS Express ausgeführt wird, wird ein Prozessfehler 502.5 vom ASP.NET Core-Modul zurückgegeben, wenn der Prozess nicht starten kann. Weitere Informationen finden Sie unter Problembehandlung bei ASP.NET Core in Azure App Service und IIS.

Datenbank-Fehlerseite

Der Ausnahmefilter der Datenbankentwicklerseite AddDatabaseDeveloperPageExceptionFilter erfasst datenbankbezogene Ausnahmen, die mithilfe von Entity Framework Core-Migrationen aufgelöst werden können. Wenn diese Ausnahmen auftreten, wird eine HTML-Antwort mit Details zu möglichen Aktionen zum Beheben des Problems generiert. Diese Seite ist nur in der Entwicklungsumgebung aktiviert. Der folgende Code wurde von den ASP.NET Core Razor Pages-Vorlagen generiert, als einzelne Benutzerkonten angegeben wurden:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();
}

Ausnahmefilter

In MVC-Apps können Ausnahmefilter global oder auf einen Controller oder eine Aktion bezogen konfiguriert werden. In Razor Pages-Apps können sie global oder auf ein Seitenmodell bezogen konfiguriert werden. Diese Filter verarbeiten jede nicht behandelte Ausnahme, die während der Ausführung eine Controlleraktion oder eines anderen Filters auftritt. Weitere Informationen finden Sie unter Filter in ASP.NET Core.

Ausnahmefilter eignen sich zum Auffangen von Ausnahmen, die in MVC-Aktionen ausgelöst werden. Sie sind jedoch nicht so flexibel wie die integrierte Middleware für die Ausnahmebehandlung, UseExceptionHandler. Es wird empfohlen, UseExceptionHandler zu verwenden, wenn Sie für die Fehlerbehandlung auf Grundlage einer ausgewählten MVC-Aktion eine andere Strategie auswählen müssen.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Modellstatusfehler

Informationen zum Behandeln von Modellstatusfehlern finden Sie unter Modellbindung und Modellvalidierung.

Zusätzliche Ressourcen

Von Tom Dykstra und Steve Smith

Dieser Artikel beschreibt grundsätzliche Vorgehensweisen zur Behandlung von Fehlern in ASP.NET Core-Web-Apps. Weitere Informationen für Web-Apps finden Sie unter Fehlerbehandlung in ASP.NET Core-Web-APIs.

Anzeigen oder Herunterladen von Beispielcode (Informationen zum Herunterladen.)

Seite mit Ausnahmen für Entwickler

Die Seite mit Ausnahmen für Entwickler enthält ausführliche Informationen zu Anforderungsausnahmen. Die ASP.NET Core-Vorlagen generieren den folgenden Code:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

Der vorangehende Code aktiviert die Seite mit Ausnahmen für Entwickler, wenn die App in der Entwicklungsumgebung ausgeführt wird.

Die Vorlagen platzieren UseDeveloperExceptionPage vor jeder Middleware, sodass Ausnahmen in der nachfolgenden Middleware abgefangen werden.

Der vorangehende Code aktiviert die Seite mit Ausnahmen für Entwickler nur dann, wenn die App in der Entwicklungsumgebung ausgeführt wird. Bei Ausführung der App in der Produktionsumgebung sollten keine detaillierten Informationen zu den Ausnahmen öffentlich angezeigt werden. Weitere Informationen zum Konfigurieren der Umgebungen finden Sie unter Verwenden von mehreren Umgebungen in ASP.NET Core.

Die Seite mit Ausnahmen für Entwickler enthält die folgenden Informationen zu der Ausnahme und der Anforderung:

  • Stapelüberwachung
  • Abfragezeichenfolgeparameter, sofern vorhanden
  • Cookies, sofern vorhanden
  • Header

Seite „Ausnahmehandler“

Um eine benutzerdefinierte Fehlerbehandlung für die Produktionsumgebung zu konfigurieren, verwenden Sie Middleware zur Ausnahmebehandlung. Die Middleware:

  • Dient zum Abfangen und Protokollieren von Ausnahmen.
  • Führt die Anforderung für die angegebene Seite oder den Controller in einer anderen Pipeline erneut aus. Die Anforderung wird nicht erneut ausgeführt, wenn die Antwort gestartet wurde. Der von der Vorlage generierte Code führt die Anforderung erneut mit /Error aus.

Im folgenden Beispiel fügt UseExceptionHandler die Middleware zur Ausnahmebehandlung in Nichtentwicklungsumgebungen hinzu:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

Die Razor Pages-App-Vorlage stellt im Ordner Pages eine Fehlerseite ( .cshtml) und PageModel-Klasse (ErrorModel) bereit. Die Projektvorlage für eine MVC-App enthält eine Fehleraktionsmethode und eine Fehleransicht im Home-Controller.

Markieren Sie die Aktionsmethode für die Fehlerbehandlung nicht mit HTTP-Methodenattributen wie HttpGet. Durch explizite Verben könnte bei einigen Anforderungen verhindert werden, dass diese Methode zum Einsatz kommt. Lassen Sie den anonymen Zugriff auf die Methode zu, wenn nicht authentifizierten Benutzern die Fehleransicht angezeigt werden soll.

Zugreifen auf die Ausnahme

Verwenden Sie IExceptionHandlerPathFeature, um auf die Ausnahme oder den Pfad der ursprünglichen Anforderung in einem Controller für die Fehlerbehandlung oder auf einer Seite zuzugreifen:

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
    public string RequestId { get; set; }
    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
    public string ExceptionMessage { get; set; }

    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

        var exceptionHandlerPathFeature =
            HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "File error thrown";
        }
        if (exceptionHandlerPathFeature?.Path == "/index")
        {
            ExceptionMessage += " from home page";
        }
    }
}

Warnung

Stellen Sie Clients keine vertraulichen Fehlerinformationen bereit. Die Bereitstellung von Fehlern ist ein Sicherheitsrisiko.

Legen Sie die Umgebung auf Produktionen fest, und erzwingen Sie eine Ausnahme, um die vorherige Seite zur Ausnahmebehandlung zu aktivieren.

Lambda-Ausdruck für Ausnahmehandler

Eine Alternative zu einer benutzerdefinierten Ausnahmebehandlungsseite ist das Angeben eines Lambda-Ausdrucks für UseExceptionHandler. Die Verwendung eines Lambda-Ausdrucks ermöglicht den Zugriff auf den Fehler, bevor die Antwort zurückgegeben wird.

Hier ist ein Beispiel der Verwendung eines Lambda-Ausdrucks für die Ausnahmebehandlung:

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
   app.UseExceptionHandler(errorApp =>
   {
        errorApp.Run(async context =>
        {
            context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
            context.Response.ContentType = "text/html";

            await context.Response.WriteAsync("<html lang=\"en\"><body>\r\n");
            await context.Response.WriteAsync("ERROR!<br><br>\r\n");

            var exceptionHandlerPathFeature = 
                context.Features.Get<IExceptionHandlerPathFeature>();

            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync("File error thrown!<br><br>\r\n");
            }

            await context.Response.WriteAsync("<a href=\"/\">Home</a><br>\r\n");
            await context.Response.WriteAsync("</body></html>\r\n");
            await context.Response.WriteAsync(new string(' ', 512)); // IE padding
        });
    });
    app.UseHsts();
}

Im vorangehenden Code wird await context.Response.WriteAsync(new string(' ', 512)); hinzugefügt, sodass der Internet Explorer-Browser die Fehlermeldung anstelle einer IE-Fehlermeldung anzeigt. Weitere Informationen finden Sie in diesem GitHub-Issue.

Warnung

Stellen Sie keine vertraulichen Fehlerinformationen aus IExceptionHandlerFeature oder IExceptionHandlerPathFeature für Clients bereit. Die Bereitstellung von Fehlern ist ein Sicherheitsrisiko.

Um in der Beispiel-App das Ergebnis des Lambda-Ausdrucks für die Ausnahmebehandlung anzuzeigen, verwenden Sie die Präprozessordirektiven ProdEnvironment und ErrorHandlerLambda, und wählen Sie auf der Startseite Ausnahme auslösen aus.

UseStatusCodePages

Ihre ASP.NET Core-App stellt für HTTP-Statuscodes wie 404 – Nicht gefunden standardmäßig keine Statuscodeseite zur Verfügung. Die App gibt einen Statuscode und einen leeren Antworttext zurück. Verwenden Sie zum Bereitstellen von Statuscodeseiten Middleware für Statuscodeseiten.

Die Middleware wird vom Paket Microsoft.AspNetCore.Diagnostics zur Verfügung gestellt.

Um für gängige Statuscodes einfache Handler im Textformat zu aktivieren, rufen Sie in der Startup.Configure-Methode UseStatusCodePages auf:

app.UseStatusCodePages();

Rufen Sie UseStatusCodePages vor Middleware zur Anforderungsverarbeitung auf (z.B. Middleware für statische Dateien und MVC-Middleware).

Wenn UseStatusCodePages nicht verwendet wird, wird beim Navigieren zu einer URL ohne Endpunkt eine browserabhängige Fehlermeldung zurückgegeben, die angibt, dass der Endpunkt nicht gefunden werden kann. Navigieren Sie zum Beispiel zu Home/Privacy2. Wenn UseStatusCodePages aufgerufen wird, gibt der Browser Folgendes zurück:

Status Code: 404; Not Found

UseStatusCodePages mit Formatzeichenfolge

Um den Inhaltstyp und Text der Antwort anzupassen, verwenden Sie die Überladung von UseStatusCodePages, die einen Inhaltstyp und eine Formatierungszeichenfolge erfordert:

app.UseStatusCodePages(
    "text/plain", "Status code page, status code: {0}");            

UseStatusCodePages mit Lambda-Ausdruck

Um benutzerdefinierten Code für die Fehlerbehandlung und das Schreiben von Antworten anzugeben, verwenden Sie die Überladung von UseStatusCodePages, die einen Lambda-Ausdruck verwendet:


app.UseStatusCodePages(async context =>
{
    context.HttpContext.Response.ContentType = "text/plain";

    await context.HttpContext.Response.WriteAsync(
        "Status code page, status code: " + 
        context.HttpContext.Response.StatusCode);
});

UseStatusCodePagesWithRedirects

Die Erweiterungsmethode UseStatusCodePagesWithRedirects:

  • Sendet den Statuscode 302 Found (Gefunden) an den Client.
  • Der Client wird an den in der URL-Vorlage angegebenen Standort umgeleitet.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");

Die URL-Vorlage kann, wie im Beispiel gezeigt, einen {0}-Platzhalter für den Statuscode enthalten. Wenn die URL-Vorlage mit einer Tilde (~) beginnt, wird ~ durch die Angabe für PathBase der App ersetzt. Wenn Sie in der App auf einen Endpunkt verweisen, müssen Sie eine MVC-Ansicht oder Razor-Seite für den Endpunkt erstellen. Ein Razor Pages-Beispiel finden Sie unter Pages/StatusCode.cshtml in der Beispiel-App.

Diese Methode wird häufig verwendet, wenn die App Folgendes tun soll:

  • Den Client an einen anderen Endpunkt umleiten, in der Regel in Fällen, in denen eine andere App den Fehler verarbeitet. Für Web-Apps gibt die Adressleiste des Browsers des Clients den umgeleiteten Endpunkt wieder.
  • Den ursprünglichen Statuscode mit der anfänglichen Umleitungsantwort nicht beibehalten und zurückgeben.

UseStatusCodePagesWithReExecute

Die Erweiterungsmethode UseStatusCodePagesWithReExecute:

  • Gibt den ursprünglichen Statuscode an den Client zurück.
  • Generiert den Antworttext durch die erneute Ausführung der Anforderungspipeline mithilfe eines alternativen Pfads.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");

Wenn Sie in der App auf einen Endpunkt verweisen, müssen Sie eine MVC-Ansicht oder Razor-Seite für den Endpunkt erstellen. Stellen Sie sicher, dass UseStatusCodePagesWithReExecute vor UseRouting platziert wird, damit die Anforderung an die Statusseite umgeleitet werden kann. Ein Razor Pages-Beispiel finden Sie unter Pages/StatusCode.cshtml in der Beispiel-App.

Diese Methode wird häufig verwendet, wenn die App Folgendes tun soll:

  • Die Anforderung ohne Umleitung an einen anderen Endpunkt verarbeiten. Für Web-Apps gibt die Adressleiste des Browsers des Clients den ursprünglich angeforderten Endpunkt wieder.
  • Den ursprünglichen Statuscode mit der Antwort beibehalten und zurückgeben.

Die Vorlagen für URL und Abfragezeichenfolgen können für den Statuscode einen Platzhalter ({0}) enthalten. Die URL-Vorlage muss mit einem Schrägstrich (/) beginnen. Wenn Sie im Pfad einen Platzhalter verwenden, vergewissern Sie sich, dass der Endpunkt (Seite oder Controller) das Pfadsegment verarbeiten kann. Eine Razor Page für Fehler sollte z. B. den Wert des optionalen Pfadsegments mit der @page-Anweisung akzeptieren:

@page "{code?}"

Der Endpunkt, der den Fehler verarbeitet, kann die ursprüngliche URL abrufen, die den Fehler generiert hat (siehe folgendes Beispiel):

var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
    OriginalURL =
        statusCodeReExecuteFeature.OriginalPathBase
        + statusCodeReExecuteFeature.OriginalPath
        + statusCodeReExecuteFeature.OriginalQueryString;
}

Markieren Sie die Aktionsmethode für die Fehlerbehandlung nicht mit HTTP-Methodenattributen wie HttpGet. Durch explizite Verben könnte bei einigen Anforderungen verhindert werden, dass diese Methode zum Einsatz kommt. Lassen Sie den anonymen Zugriff auf die Methode zu, wenn nicht authentifizierten Benutzern die Fehleransicht angezeigt werden soll.

Deaktivieren von Statuscodeseiten

Verwenden Sie das Attribut [SkipStatusCodePages], um Statuscodeseiten für einen MVC-Controller oder eine MVC-Aktionsmethode zu deaktivieren.

Verwenden Sie IStatusCodePagesFeature, um Statuscodeseiten für bestimmte Anforderungen in der Handlermethode von Razor Pages oder in einem MVC-Controller zu deaktivieren:

var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();

if (statusCodePagesFeature != null)
{
    statusCodePagesFeature.Enabled = false;
}

Ausnahmebehandlungscode

Code auf Seiten zur Ausnahmebehandlung kann Ausnahmen auslösen. Es ist häufig empfehlenswert, wenn Produktionsfehlerseiten nur statische Inhalte aufweisen.

Antwortheader

Nachdem die Header für eine Antwort gesendet wurden:

  • Die App kann den Statuscode der Antwort nicht ändern.
  • Weder Ausnahmeseiten noch Handler können ausgeführt werden. Die Antwort muss abgeschlossen oder die Verbindung unterbrochen werden.

Sichere Ausnahmebehandlung

Neben der Ausnahmebehandlungslogik in Ihrer App kann die HTTP-Serverimplementierung einige Ausnahmebehandlungen durchführen. Wenn der Server eine Ausnahme erfasst, bevor die Antwortheader gesendet werden, sendet der Server die Antwort 500 – Interner Serverfehler ohne Antworttext. Wenn der Server eine Ausnahme auffängt, nachdem die Antwortheader gesendet wurden, schließt der Server die Verbindung. Anforderungen, die nicht von Ihrer App verarbeitet werden, werden vom Server verarbeitet. Jede Ausnahme, die bei der Anforderungsverarbeitung durch den Server auftritt, wird durch die Ausnahmebehandlung des Servers verarbeitet. Die benutzerdefinierten Fehlerseiten der App, Middleware zur Fehlerbehandlung und Filter haben keine Auswirkungen auf dieses Verhalten.

Fehlerbehandlung während des Starts

Nur auf Hostebene können Ausnahmen behandelt werden, die während des Starts einer App auftreten. Der Host kann für das Erfassen von Startfehlern und Erfassen detaillierter Fehler konfiguriert werden.

Die Hostingebene kann nur dann für einen beim Start erfassten Fehler eine Fehlerseite anzeigen, wenn der Fehler nach der Bindung an die Hostadresse bzw. den Port auftritt. Wenn die Bindung misslingt:

  • Die Hostebene protokolliert eine kritische Ausnahme.
  • Der DotNet-Prozess stürzt ab.
  • Wenn der HTTP-Server Kestrel heißt, wird keine Fehlerseite angezeigt.

Wenn sie auf IIS (oder Azure App Service) oder IIS Express ausgeführt wird, wird ein Prozessfehler 502.5 vom ASP.NET Core-Modul zurückgegeben, wenn der Prozess nicht starten kann. Weitere Informationen finden Sie unter Problembehandlung bei ASP.NET Core in Azure App Service und IIS.

Datenbank-Fehlerseite

Die Middleware „Datenbank-Fehlerseite“ erfasst datenbankbezogene Ausnahmen, die mithilfe von Entity Framework-Migrationen aufgelöst werden können. Wenn diese Ausnahmen auftreten, wird eine HTML-Antwort mit Details zu möglichen Aktionen zum Beheben des Problems generiert. Diese Seite darf nur in der Entwicklungsumgebung aktiviert werden. Aktivieren Sie die Seite, indem Sie Startup.Configure Code hinzufügen:

if (env.IsDevelopment())
{
    app.UseDatabaseErrorPage();
}

UseDatabaseErrorPage benötigt das Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore-NuGet-Paket.

Ausnahmefilter

In MVC-Apps können Ausnahmefilter global oder auf einen Controller oder eine Aktion bezogen konfiguriert werden. In Razor Pages-Apps können sie global oder auf ein Seitenmodell bezogen konfiguriert werden. Diese Filter verarbeiten jede nicht behandelte Ausnahme, die während der Ausführung eine Controlleraktion oder eines anderen Filters auftritt. Weitere Informationen finden Sie unter Filter in ASP.NET Core.

Tipp

Ausnahmefilter eignen sich zum Auffangen von Ausnahmen, die in MVC-Aktionen auftreten. Sie sind jedoch nicht so flexibel wie Middleware für die Ausnahmebehandlung. Es wird empfohlen, die Middleware zu verwenden. Verwenden Sie Filter nur dann, wenn Sie für die Fehlerbehandlung auf Grundlage einer ausgewählten MVC-Aktion eine andere Strategie wählen müssen.

Modellstatusfehler

Informationen zum Behandeln von Modellstatusfehlern finden Sie unter Modellbindung und Modellvalidierung.

Zusätzliche Ressourcen