Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Note
Det här är inte den senaste versionen av den här artikeln. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln.
Warning
Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln.
Important
Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.
För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln.
Den här artikeln beskriver vanliga metoder för att hantera fel i ASP.NET Core-webbappar. Se även Hantera fel i ASP.NET Core-API:er.
Vägledning för Blazor felhantering som lägger till eller ersätter vägledningen i den här artikeln finns i Hantera fel i ASP.NET Core Blazor-appar.
Undantagssida för utvecklare
undantagssidan för utvecklare visar detaljerad information om ohanterade undantag för begäranden. Den använder DeveloperExceptionPageMiddleware för att samla in synkrona och asynkrona undantag från HTTP-pipelinen och för att generera felsvar. Undantagssidan för utvecklare körs tidigt i middleware-pipelinen, så att den kan fånga ohanterade undantag som genereras i efterföljande mellanprogram.
ASP.NET Core-appar aktiverar utvecklarens undantagssida som standard när båda:
- Kör i utvecklingsmiljö .
- Appen skapades med de aktuella mallarna, dvs. med hjälp av WebApplication.CreateBuilder.
Appar som skapats med hjälp av tidigare mallar, d.v.s. med hjälp av WebHost.CreateDefaultBuilder, kan aktivera undantagssidan för utvecklare genom att anropa app.UseDeveloperExceptionPage.
Warning
Aktivera inte undantagssidan för utvecklare om inte appen körs i utvecklingsmiljön. Dela inte detaljerad undantagsinformation offentligt när appen körs i produktion. Mer information om hur du konfigurerar miljöer finns i ASP.NET Core Runtime-miljöer.
Sidan Undantag för utvecklare kan innehålla följande information om undantaget och begäran:
- Stackspårning
- Frågesträngsparametrar, om några
- Cookies, om några
- Headers
- Slutpunktsmetadata, om några
Undantagssidan för utvecklare är inte garanterad att ange någon information. Använd logg för fullständig felinformation.
Följande bild visar ett exempel på en undantagssida för utvecklare med animering för att visa flikarna och informationen som visas:
              
               
              
              
            
Som svar på en begäran med en Accept: text/plain-rubrik returnerar undantagssidan för utvecklare oformaterad text i stället för HTML. Till exempel:
Status: 500 Internal Server Error
Time: 9.39 msSize: 480 bytes
FormattedRawHeadersRequest
Body
text/plain; charset=utf-8, 480 bytes
System.InvalidOperationException: Sample Exception
   at WebApplicationMinimal.Program.<>c.<Main>b__0_0() in C:\Source\WebApplicationMinimal\Program.cs:line 12
   at lambda_method1(Closure, Object, HttpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
=======
Accept: text/plain
Host: localhost:7267
traceparent: 00-0eab195ea19d07b90a46cd7d6bf2f
Undantagshanteringsida
Om du vill konfigurera en anpassad felhanteringssida för Produktionsmiljöanropar du UseExceptionHandler. Denna undantagshanterande mellanprogramvara:
- Fångar upp och loggar ohanterade undantag.
- Utför begäran på nytt i en alternativ pipeline med den angivna sökvägen. Begäran utförs inte igen om svaret redan har påbörjats. Den mallgenererade koden kör begäran igen med hjälp av sökvägen /Error.
Warning
Om den alternativa pipelinen genererar ett eget undantag, överväxlar Undantagshantering mellanprogram det ursprungliga undantaget.
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- För den UseExceptionHandler(IApplicationBuilder, String)-överbelastning som används i mallar ändras endast begärans sökväg och routdata rensas. Begärdata, såsom rubriker, metod och objekt, återanvänds alla som de är.
- Begränsade tjänster förblir desamma.
I följande exempel lägger UseExceptionHandler till undantagshanteringsmellanprogram i miljöer som inte är utvecklingsmiljöer:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Appmallen Razor Pages innehåller en felsida (.cshtml) och PageModel -klass (ErrorModel) i mappen Pages. För en MVC-app innehåller projektmallen en Error-åtgärdsmetod och en felvy för den Home kontrollanten.
Undantagshanteringsmellanprogrammet kör begäran igen med hjälp av den ursprungliga HTTP-metoden. Om en slutpunkt för felhanterare är begränsad till en specifik uppsättning HTTP-metoder körs den endast för dessa HTTP-metoder. Till exempel körs en MVC-kontrollantåtgärd som använder attributet [HttpGet] endast för GET-begäranden. För att säkerställa att alla begäranden når sidan för anpassad felhantering ska du inte begränsa dem till en specifik uppsättning HTTP-metoder.
Så här hanterar du undantag på olika sätt baserat på den ursprungliga HTTP-metoden:
- Skapa flera hanteringsmetoder för Razor Pages. Använd till exempel OnGetför att hantera GET-undantag och användaOnPostför att hantera POST-undantag.
- För MVC använder du HTTP-verbattribut på flera åtgärder. Använd till exempel [HttpGet]för att hantera GET-undantag och använda[HttpPost]för att hantera POST-undantag.
Om du vill tillåta oautentiserade användare att visa sidan för anpassad felhantering kontrollerar du att den stöder anonym åtkomst.
Få åtkomst till undantaget
Använd IExceptionHandlerPathFeature för att komma åt undantaget och den ursprungliga sökvägen för begäran i en felhanterare. I följande exempel används IExceptionHandlerPathFeature för att få mer information om undantaget som utlöstes:
[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; }
    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        var exceptionHandlerPathFeature =
            HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "The file was not found.";
        }
        if (exceptionHandlerPathFeature?.Path == "/")
        {
            ExceptionMessage ??= string.Empty;
            ExceptionMessage += " Page: Home.";
        }
    }
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
Lambda för undantagshanterare
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet innan svaret returneras.
Följande kod använder en lambda för undantagshantering:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;
            await context.Response.WriteAsync("An exception was thrown.");
            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();
            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync(" The file was not found.");
            }
            if (exceptionHandlerPathFeature?.Path == "/")
            {
                await context.Response.WriteAsync(" Page: Home.");
            }
        });
    });
    app.UseHsts();
}
Ett annat sätt att använda en lambda är att ange statuskoden baserat på undantagstypen, som i följande exempel:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseExceptionHandler(new ExceptionHandlerOptions
    {
        StatusCodeSelector = ex => ex is TimeoutException
            ? StatusCodes.Status503ServiceUnavailable
            : StatusCodes.Status500InternalServerError
    });
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
IExceptionHandler
              IExceptionHandler är ett gränssnitt som ger utvecklaren ett återanrop för hantering av kända undantag på en central plats. Gränssnittet innehåller en enda metod, TryHandleAsync, som tar emot en HttpContext och en Exception parameter.
              IExceptionHandler implementeringar registreras genom att anropa IServiceCollection.AddExceptionHandler<T>. Livslängden för en IExceptionHandler instans är singleton. Flera implementeringar kan läggas till och de anropas i den registrerade ordningen.
Undantagshantering av mellanprogram itererar via registrerade undantagshanterare i ordning tills en returnerar true från TryHandleAsync, vilket indikerar att undantaget har hanterats. Om en undantagshanterare hanterar ett undantag kan den returnera true för att stoppa bearbetningen. Om ett undantag inte hanteras av någon undantagshanterare återgår kontrollen till standardbeteendet och alternativen från mellanprogrammet.
Från och med .NET 10 är standardbeteendet att förhindra utsläpp av diagnostik, till exempel loggar och mått för hanterade undantag (när TryHandleAsync returnerar true). Detta skiljer sig från tidigare versioner (.NET 8 och 9) där diagnostik alltid genererades oavsett om undantaget hanterades. Standardbeteendet kan ändras genom att ange SuppressDiagnosticsCallback.
I följande exempel visas en IExceptionHandler implementering:
using Microsoft.AspNetCore.Diagnostics;
namespace ErrorHandlingSample
{
    public class CustomExceptionHandler : IExceptionHandler
    {
        private readonly ILogger<CustomExceptionHandler> logger;
        public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
        {
            this.logger = logger;
        }
        public ValueTask<bool> TryHandleAsync(
            HttpContext httpContext,
            Exception exception,
            CancellationToken cancellationToken)
        {
            var exceptionMessage = exception.Message;
            logger.LogError(
                "Error Message: {exceptionMessage}, Time of occurrence {time}",
                exceptionMessage, DateTime.UtcNow);
            // Return false to continue with the default behavior
            // - or - return true to signal that this exception is handled
            return ValueTask.FromResult(false);
        }
    }
}
I följande exempel visas hur du registrerar en IExceptionHandler implementering för beroendeinmatning:
using ErrorHandlingSample;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// Remaining Program.cs code omitted for brevity
När föregående kod körs i utvecklingsmiljön:
- 
              CustomExceptionHandleranropas först för att hantera ett undantag.
- Efter att ha loggat undantaget returnerar TryHandleAsync-metodenfalse, så visas undantagssidan för utvecklare.
I andra miljöer:
- 
              CustomExceptionHandleranropas först för att hantera ett undantag.
- När du har loggat undantaget returnerar TryHandleAsync-metodenfalse, så/Error-sidan visas.
SuppressDiagnosticsCallback
Från och med .NET 10 kan du styra om undantagshanteringsmiddleware skriver diagnostik för behandlade undantag genom att konfigurera SuppressDiagnosticsCallback-egenskapen på ExceptionHandlerOptions. Det här återanropet tar emot undantagskontexten och gör att du kan avgöra om diagnostik ska undertryckas baserat på det specifika undantaget eller begäran.
Om du vill återgå till .NET 8- och .NET 9-beteendet där diagnostik alltid genereras för hanterade undantag ställer du in återanropet till att alltid returnera false:
app.UseExceptionHandler(new ExceptionHandlerOptions
{
    SuppressDiagnosticsCallback = context => false
});
Du kan också villkorligt undertrycka diagnostik baserat på undantagstyp eller annan kontext:
app.UseExceptionHandler(new ExceptionHandlerOptions
{
    SuppressDiagnosticsCallback = context => context.Exception is ArgumentException
});
När ett undantag inte hanteras av någon IExceptionHandler implementering (alla hanterare returnerar false från TryHandleAsync) återgår kontrollen till standardbeteendet och alternativen från mellanprogrammet, och diagnostiken genereras enligt mellanprogrammets standardbeteende.
UseStatusCodePages
Som standard tillhandahåller en ASP.NET Core-app inte någon statuskodsida för HTTP-felstatuskoder, till exempel 404 – Hittades inte. När appen anger en HTTP 400-599-felstatuskod som inte har någon brödtext returneras statuskoden och en tom svarstext. Om du vill aktivera standardhanterare med endast text för vanliga felstatuskoder anropar du UseStatusCodePages i Program.cs:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages();
Anropa UseStatusCodePages innan du begär hantering av mellanprogram. Anropa till exempel UseStatusCodePages före mellanskiktet för statiska filer och mellanskiktet för slutpunkter.
När UseStatusCodePages inte används returnerar navigering till en URL utan en slutpunkt ett webbläsarberoende felmeddelande som anger att slutpunkten inte kan hittas. När UseStatusCodePages anropas returnerar webbläsaren följande svar:
Status Code: 404; Not Found
              UseStatusCodePages används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
Note
Mellanprogrammet för statuskodsidor gör inte fånga undantag. Om du vill ange en anpassad felhanteringssida använder du sidan undantagshanterare.
Använd UseStatusCodePages med formatsträng
Om du vill anpassa svarsinnehållstypen och texten använder du överlagringen av UseStatusCodePages som tar en innehållstyp och formatsträng:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
I föregående kod är {0} en platshållare för felkoden.
              UseStatusCodePages med en formatsträng används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePages med lambda
Om du vill ange anpassad felhanterings- och svarsskrivningskod, använd en överlagring av UseStatusCodePages som tar ett lambda-uttryck:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
    // using static System.Net.Mime.MediaTypeNames;
    statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
    await statusCodeContext.HttpContext.Response.WriteAsync(
        $"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
              UseStatusCodePages med en lambda används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects utökningsmetod:
- Skickar en 302 – hittad statuskod till klienten.
- Omdirigerar klienten till slutpunkten för felhantering som anges i URL-mallen. Slutpunkten för felhantering visar vanligtvis felinformation och returnerar HTTP 200.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL-mallen kan innehålla en {0} platshållare för statuskoden, enligt föregående kod. Om URL-mallen börjar med ~ (tilde) ersätts ~ av appens PathBase. När du anger en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen:
- Ska omdirigera klienten till en annan slutpunkt, vanligtvis i fall där en annan app bearbetar felet. För webbappar återspeglar klientens webbläsaradressfält den omdirigerade slutpunkten.
- Bör inte bevara och returnera den ursprungliga statuskoden med det första omdirigeringssvaret.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute utökningsmetod:
- Genererar svarstextens innehåll genom att köra begärandepipelinen igen med hjälp av en alternativ sökväg.
- Ändrar inte statuskoden före eller efter att pipelinen körts om.
Den nya pipelinekörningen kan ändra svarets statuskod eftersom den nya pipelinen har fullständig kontroll över statuskoden. Om den nya pipelinen inte ändrar statuskoden skickas den ursprungliga statuskoden till klienten.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Om en slutpunkt i appen har angetts skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen ska:
- Bearbeta begäran utan att omdirigera till en annan slutpunkt. För webbappar återspeglar klientens webbläsaradressfält den ursprungligen begärda slutpunkten.
- Bevara och returnera den ursprungliga statuskoden med svaret.
URL-mallen måste börja med / och kan innehålla en platshållare {0} för statuskoden. Skicka statuskoden som en frågesträngsparameter genom att skicka ett andra argument till UseStatusCodePagesWithReExecute. Till exempel:
var app = builder.Build();  
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Slutpunkten som bearbetar felet kan hämta den ursprungliga URL:en som genererade felet, enligt följande exempel:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
    public int OriginalStatusCode { get; set; }
    public string? OriginalPathAndQuery { get; set; }
    public void OnGet(int statusCode)
    {
        OriginalStatusCode = statusCode;
        var statusCodeReExecuteFeature =
            HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
        if (statusCodeReExecuteFeature is not null)
        {
            OriginalPathAndQuery = $"{statusCodeReExecuteFeature.OriginalPathBase}"
                                    + $"{statusCodeReExecuteFeature.OriginalPath}"
                                    + $"{statusCodeReExecuteFeature.OriginalQueryString}";
        }
    }
}
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- Begränsade tjänster förblir desamma.
Inaktivera statuskodsidor
Om du vill inaktivera statuskodsidor för en MVC-kontrollant eller åtgärdsmetod använder du attributet [SkipStatusCodePages].
Om du vill inaktivera statuskodsidor för specifika begäranden i en Razor Pages-hanteringsmetod eller i en MVC-styrenhet använder du IStatusCodePagesFeature:
public void OnGet()
{
    var statusCodePagesFeature =
        HttpContext.Features.Get<IStatusCodePagesFeature>();
    if (statusCodePagesFeature is not null)
    {
        statusCodePagesFeature.Enabled = false;
    }
}
Kod för undantagshantering
Kod i undantagshanteringssidor kan också utlösa undantag. Sidor med produktionsfel bör testas noggrant och vara extra noggranna för att undvika egna undantag.
Svarsrubriker
När rubrikerna för ett svar har skickats:
- Appen kan inte ändra svarets statuskod.
- Undantagssidor eller hanterare kan inte köras. Svaret måste slutföras eller så avbryts anslutningen.
Hantering av serverfel
Förutom logiken för undantagshantering i en app kan HTTP-serverimplementering hantera vissa undantag. Om servern upptäcker ett undantag innan svarshuvuden skickas skickar servern ett 500 - Internal Server Error svar utan svarstext. Om servern får ett undantag efter att svarsrubriker har skickats, stänger servern anslutningen. Begäranden som inte hanteras av appen hanteras av servern. Alla undantag som inträffar när servern hanterar begäran hanteras av serverns undantagshantering. Appens anpassade felsidor, undantagshantering av mellanprogram och filter påverkar inte det här beteendet.
Undantagshantering vid start
Endast värdlagret kan hantera undantag som sker under appstarten. Värden kan konfigureras för att fånga startfel och fånga detaljerade fel.
Värdlagret kan visa en felsida för ett insamlat startfel endast om felet inträffar efter värdadress/portbindning. Om bindningen misslyckas:
- Värdlagret loggar ett kritiskt undantag.
- Dotnet-processen kraschar.
- Ingen felsida visas när HTTP-servern är Kestrel.
När du kör på IIS (eller Azure App Service) eller IIS Expressreturneras en 502.5 – Processfel av ASP.NET Core-modulen om processen inte kan starta. Mer information finns i Felsöka ASP.NET Core i Azure App Service och IIS.
Databasfelsida
Undantagsfiltret för databasutvecklare AddDatabaseDeveloperPageExceptionFilter samlar in databasrelaterade undantag som kan lösas med hjälp av Entity Framework Core-migreringar. När dessa undantag inträffar genereras ett HTML-svar med information om möjliga åtgärder för att lösa problemet. Den här sidan är endast aktiverad i utvecklingsmiljön. Följande kod lägger till undantagsfiltret för databasutvecklarens sida:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Undantagsfilter
I MVC-appar kan undantagsfilter konfigureras globalt eller per kontrollant eller per åtgärd. I Razor Pages-appar kan de konfigureras globalt eller per sidmodell. Dessa filter hanterar alla ohanterade undantag som inträffar under exekveringen av en controlleråtgärd eller ett annat filter. Mer information finns i filter i ASP.NET Core.
Undantagsfilter är användbara för att fånga undantag som inträffar inom MVC-action, men de är inte lika flexibla som den inbyggda undantagshantermellanvara, UseExceptionHandler. Vi rekommenderar att du använder UseExceptionHandler, såvida du inte behöver utföra felhantering på olika sätt baserat på vilken MVC-åtgärd som väljs.
Modelltillståndsfel
Information om hur du hanterar modelltillståndsfel finns i Modellbindning och modellverifiering.
Probleminformation
Probleminformation är inte det enda svarsformatet som beskriver ett HTTP API-fel, men de används ofta för att rapportera fel för HTTP-API:er.
Tjänsten probleminformation implementerar IProblemDetailsService-gränssnittet, som har stöd för att skapa probleminformation i ASP.NET Core. 
              AddProblemDetails(IServiceCollection)-tilläggsmetoden på IServiceCollection registrerar standardimplementeringen IProblemDetailsService.
I ASP.NET Core-appar genererar följande mellanprogramvara HTTP-svar med probleminformation när AddProblemDetails anropas, förutom när HTTP-huvudet för Accept-begäran inte innehåller någon av de innehållstyper som stöds av den registrerade IProblemDetailsWriter (standard: application/json):
- ExceptionHandlerMiddleware: Genererar ett probleminformationssvar när en anpassad hanterare inte har definierats.
- StatusCodePagesMiddleware: Genererar ett probleminformationssvar som standard.
- 
              DeveloperExceptionPageMiddleware: Genererar ett probleminformationssvar under utveckling när HTTP-huvudet för Acceptbegäran inte innehållertext/html.
Följande kod konfigurerar appen för att generera ett probleminformationssvar för alla HTTP-klient- och serverfelsvar som inte har brödtextinnehåll ännu:
builder.Services.AddProblemDetails();
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
I nästa avsnitt visas hur du anpassar svarstexten för probleminformation.
Anpassa probleminformation
Automatisk skapande av en ProblemDetails kan anpassas med något av följande alternativ:
- Använd ProblemDetailsOptions.CustomizeProblemDetails
- Använd en anpassad IProblemDetailsWriter
- Anropa IProblemDetailsServicei ett mellanprogram
              CustomizeProblemDetails åtgärd
Den genererade probleminformationen kan anpassas med hjälp av CustomizeProblemDetailsoch anpassningarna tillämpas på all probleminformation som genereras automatiskt.
Följande kod använder ProblemDetailsOptions för att ange CustomizeProblemDetails:
builder.Services.AddProblemDetails(options =>
    options.CustomizeProblemDetails = ctx =>
            ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName));
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
Ett HTTP Status 400 Bad Request slutpunktsresultat skapar till exempel följande svarstext för probleminformation:
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "Bad Request",
  "status": 400,
  "nodeId": "my-machine-name"
}
Anpassad IProblemDetailsWriter
En IProblemDetailsWriter implementering kan skapas för avancerade anpassningar.
public class SampleProblemDetailsWriter : IProblemDetailsWriter
{
    // Indicates that only responses with StatusCode == 400
    // are handled by this writer. All others are
    // handled by different registered writers if available.
    public bool CanWrite(ProblemDetailsContext context)
        => context.HttpContext.Response.StatusCode == 400;
    public ValueTask WriteAsync(ProblemDetailsContext context)
    {
        // Additional customizations.
        // Write to the response.
        var response = context.HttpContext.Response;
        return new ValueTask(response.WriteAsJsonAsync(context.ProblemDetails));
    }
}
              
              Obs! När du använder en anpassad IProblemDetailsWritermåste den anpassade IProblemDetailsWriter registreras innan du anropar AddRazorPages, AddControllers, AddControllersWithViewseller AddMvc:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IProblemDetailsWriter, SampleProblemDetailsWriter>();
var app = builder.Build();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsWriter>() is
            { } problemDetailsService)
        {
            if (problemDetailsService.CanWrite(new ProblemDetailsContext() { HttpContext = context }))
            {
                (string Detail, string Type) details = mathErrorFeature.MathError switch
                {
                    MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                        "https://en.wikipedia.org/wiki/Division_by_zero"),
                    _ => ("Negative or complex numbers are not valid input.",
                        "https://en.wikipedia.org/wiki/Square_root")
                };
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                    {
                        Title = "Bad Input",
                        Detail = details.Detail,
                        Type = details.Type
                    }
                });
            }
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.DivisionByZeroError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.NegativeRadicandError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.Run();
Probleminformation från Middleware
Ett annat sätt att använda ProblemDetailsOptions med CustomizeProblemDetails är att ange ProblemDetails i mellanprogram. Ett probleminformationssvar kan skrivas genom att anropa IProblemDetailsService.WriteAsync:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsService>() is
                                                           { } problemDetailsService)
        {
            (string Detail, string Type) details = mathErrorFeature.MathError switch
            {
                MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                "https://en.wikipedia.org/wiki/Division_by_zero"),
                _ => ("Negative or complex numbers are not valid input.", 
                "https://en.wikipedia.org/wiki/Square_root")
            };
            await problemDetailsService.WriteAsync(new ProblemDetailsContext
            {
                HttpContext = context,
                ProblemDetails =
                {
                    Title = "Bad Input",
                    Detail = details.Detail,
                    Type = details.Type
                }
            });
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.DivisionByZeroError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.NegativeRadicandError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.MapControllers();
app.Run();
I föregående kod returnerar de minimala API-slutpunkterna /divide och /squareroot det förväntade anpassade problemsvaret vid felindata.
API-kontrollantens slutpunkter returnerar standardfelsvaret vid felindata, inte det anpassade problemsvaret. Standardproblemsvaret returneras eftersom API-kontrollanten har skrivit till svarsströmmen Probleminformation för felstatuskoderinnan IProblemDetailsService.WriteAsync anropas och svaret inte skrivs igen.
Följande ValuesController returnerar BadRequestResult, vilket skriver till svarsströmmen och därför förhindrar att ett anpassat problemsvar returneras.
[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // /api/values/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Följande Values3Controller returnerar ControllerBase.Problem så att det förväntade anpassade problemresultatet returneras:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values3Controller : ControllerBase
{
    // /api/values3/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Divison by zero is not defined.",
                type: "https://en.wikipedia.org/wiki/Division_by_zero",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values3/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Negative or complex numbers are not valid input.",
                type: "https://en.wikipedia.org/wiki/Square_root",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Skapa en ProblemDetails-last för undantag
Tänk på följande app:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
app.MapControllers();
app.Run();
När ett undantag inträffar i icke-utvecklingsmiljöer är följande ett standardsvar ProblemDetails som returneras till klienten:
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title":"An error occurred while processing your request.",
"status":500,"traceId":"00-b644<snip>-00"
}
För de flesta appar är föregående kod allt som behövs för undantag. I följande avsnitt visas dock hur du får mer detaljerade problemsvar.
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet och skriva ett probleminformationssvar med IProblemDetailsService.WriteAsync:
using Microsoft.AspNetCore.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = Text.Plain;
            var title = "Bad Input";
            var detail = "Invalid input";
            var type = "https://errors.example.com/badInput";
            if (context.RequestServices.GetService<IProblemDetailsService>() is
                { } problemDetailsService)
            {
                var exceptionHandlerFeature =
               context.Features.Get<IExceptionHandlerFeature>();
                var exceptionType = exceptionHandlerFeature?.Error;
                if (exceptionType != null &&
                   exceptionType.Message.Contains("infinity"))
                {
                    title = "Argument exception";
                    detail = "Invalid input";
                    type = "https://errors.example.com/argumentException";
                }
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                {
                    Title = title,
                    Detail = detail,
                    Type = type
                }
                });
            }
        });
    });
}
app.MapControllers();
app.Run();
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
En annan metod för att generera probleminformation är att använda NuGet-paketet från tredje part Hellang.Middleware.ProblemDetails som kan användas för att mappa undantag och klientfel till probleminformation.
Ytterligare resurser
- Visa eller ladda ned exempelkod (hur du laddar ned)
- Felsöka ASP.NET Core i Azure App Service och IIS-
- Vanliga fel vid felsökning för Azure App Service och IIS med ASP.NET Core
- Hantera fel i ASP.NET Core-API:er
- 
              Icke-bakåtkompatibel ändring: Undantagsdiagnostik ignoreras när IExceptionHandler.TryHandleAsyncreturnerar sant
Den här artikeln beskriver vanliga metoder för att hantera fel i ASP.NET Core-webbappar. Se även Hantera fel i ASP.NET Core-API:er.
Vägledning för Blazor felhantering som lägger till eller ersätter vägledningen i den här artikeln finns i Hantera fel i ASP.NET Core Blazor-appar.
Undantagssida för utvecklare
undantagssidan för utvecklare visar detaljerad information om ohanterade undantag för begäranden. Den använder DeveloperExceptionPageMiddleware för att samla in synkrona och asynkrona undantag från HTTP-pipelinen och för att generera felsvar. Undantagssidan för utvecklare körs tidigt i middleware-pipelinen, så att den kan fånga ohanterade undantag som genereras i efterföljande mellanprogram.
ASP.NET Core-appar aktiverar utvecklarens undantagssida som standard när båda:
- Kör i utvecklingsmiljö .
- Appen skapades med de aktuella mallarna, dvs. med hjälp av WebApplication.CreateBuilder.
Appar som skapats med hjälp av tidigare mallar, d.v.s. med hjälp av WebHost.CreateDefaultBuilder, kan aktivera undantagssidan för utvecklare genom att anropa app.UseDeveloperExceptionPage.
Warning
Aktivera inte undantagssidan för utvecklare om inte appen körs i utvecklingsmiljön. Dela inte detaljerad undantagsinformation offentligt när appen körs i produktion. Mer information om hur du konfigurerar miljöer finns i ASP.NET Core Runtime-miljöer.
Sidan Undantag för utvecklare kan innehålla följande information om undantaget och begäran:
- Stackspårning
- Frågesträngsparametrar, om några
- Cookies, om några
- Headers
- Slutpunktsmetadata, om några
Undantagssidan för utvecklare är inte garanterad att ange någon information. Använd logg för fullständig felinformation.
Följande bild visar ett exempel på en undantagssida för utvecklare med animering för att visa flikarna och informationen som visas:
              
               
              
              
            
Som svar på en begäran med en Accept: text/plain-rubrik returnerar undantagssidan för utvecklare oformaterad text i stället för HTML. Till exempel:
Status: 500 Internal Server Error
Time: 9.39 msSize: 480 bytes
FormattedRawHeadersRequest
Body
text/plain; charset=utf-8, 480 bytes
System.InvalidOperationException: Sample Exception
   at WebApplicationMinimal.Program.<>c.<Main>b__0_0() in C:\Source\WebApplicationMinimal\Program.cs:line 12
   at lambda_method1(Closure, Object, HttpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
=======
Accept: text/plain
Host: localhost:7267
traceparent: 00-0eab195ea19d07b90a46cd7d6bf2f
Undantagshanteringsida
Om du vill konfigurera en anpassad felhanteringssida för Produktionsmiljöanropar du UseExceptionHandler. Denna undantagshanterande mellanprogramvara:
- Fångar upp och loggar ohanterade undantag.
- Utför begäran på nytt i en alternativ pipeline med den angivna sökvägen. Begäran utförs inte igen om svaret redan har påbörjats. Den mallgenererade koden kör begäran igen med hjälp av sökvägen /Error.
Warning
Om den alternativa pipelinen genererar ett eget undantag, överväxlar Undantagshantering mellanprogram det ursprungliga undantaget.
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- För den UseExceptionHandler(IApplicationBuilder, String)-överbelastning som används i mallar ändras endast begärans sökväg och routdata rensas. Begärdata, såsom rubriker, metod och objekt, återanvänds alla som de är.
- Begränsade tjänster förblir desamma.
I följande exempel lägger UseExceptionHandler till undantagshanteringsmellanprogram i miljöer som inte är utvecklingsmiljöer:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Appmallen Razor Pages innehåller en felsida (.cshtml) och PageModel -klass (ErrorModel) i mappen Pages. För en MVC-app innehåller projektmallen en Error-åtgärdsmetod och en felvy för den Home kontrollanten.
Undantagshanteringsmellanprogrammet kör begäran igen med hjälp av den ursprungliga HTTP-metoden. Om en slutpunkt för felhanterare är begränsad till en specifik uppsättning HTTP-metoder körs den endast för dessa HTTP-metoder. Till exempel körs en MVC-kontrollantåtgärd som använder attributet [HttpGet] endast för GET-begäranden. För att säkerställa att alla begäranden når sidan för anpassad felhantering ska du inte begränsa dem till en specifik uppsättning HTTP-metoder.
Så här hanterar du undantag på olika sätt baserat på den ursprungliga HTTP-metoden:
- Skapa flera hanteringsmetoder för Razor Pages. Använd till exempel OnGetför att hantera GET-undantag och användaOnPostför att hantera POST-undantag.
- För MVC använder du HTTP-verbattribut på flera åtgärder. Använd till exempel [HttpGet]för att hantera GET-undantag och använda[HttpPost]för att hantera POST-undantag.
Om du vill tillåta oautentiserade användare att visa sidan för anpassad felhantering kontrollerar du att den stöder anonym åtkomst.
Få åtkomst till undantaget
Använd IExceptionHandlerPathFeature för att komma åt undantaget och den ursprungliga sökvägen för begäran i en felhanterare. I följande exempel används IExceptionHandlerPathFeature för att få mer information om undantaget som utlöstes:
[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; }
    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        var exceptionHandlerPathFeature =
            HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "The file was not found.";
        }
        if (exceptionHandlerPathFeature?.Path == "/")
        {
            ExceptionMessage ??= string.Empty;
            ExceptionMessage += " Page: Home.";
        }
    }
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
Lambda för undantagshanterare
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet innan svaret returneras.
Följande kod använder en lambda för undantagshantering:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;
            await context.Response.WriteAsync("An exception was thrown.");
            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();
            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync(" The file was not found.");
            }
            if (exceptionHandlerPathFeature?.Path == "/")
            {
                await context.Response.WriteAsync(" Page: Home.");
            }
        });
    });
    app.UseHsts();
}
Ett annat sätt att använda en lambda är att ange statuskoden baserat på undantagstypen, som i följande exempel:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseExceptionHandler(new ExceptionHandlerOptions
    {
        StatusCodeSelector = ex => ex is TimeoutException
            ? StatusCodes.Status503ServiceUnavailable
            : StatusCodes.Status500InternalServerError
    });
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
IExceptionHandler
IExceptionHandler är ett gränssnitt som ger utvecklaren ett återanrop för hantering av kända undantag på en central plats.
              IExceptionHandler implementeringar registreras genom att anropa IServiceCollection.AddExceptionHandler<T>. Livslängden för en IExceptionHandler instans är singleton. Flera implementeringar kan läggas till och de anropas i den registrerade ordningen.
Om en undantagshanterare hanterar en begäran kan den returnera true för att stoppa bearbetningen. Om ett undantag inte hanteras av någon undantagshanterare återgår kontrollen till standardbeteendet och alternativen från mellanprogrammet. Olika mått och loggar genereras för hanterade och ohanterade undantag.
I följande exempel visas en IExceptionHandler implementering:
using Microsoft.AspNetCore.Diagnostics;
namespace ErrorHandlingSample
{
    public class CustomExceptionHandler : IExceptionHandler
    {
        private readonly ILogger<CustomExceptionHandler> logger;
        public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
        {
            this.logger = logger;
        }
        public ValueTask<bool> TryHandleAsync(
            HttpContext httpContext,
            Exception exception,
            CancellationToken cancellationToken)
        {
            var exceptionMessage = exception.Message;
            logger.LogError(
                "Error Message: {exceptionMessage}, Time of occurrence {time}",
                exceptionMessage, DateTime.UtcNow);
            // Return false to continue with the default behavior
            // - or - return true to signal that this exception is handled
            return ValueTask.FromResult(false);
        }
    }
}
I följande exempel visas hur du registrerar en IExceptionHandler implementering för beroendeinmatning:
using ErrorHandlingSample;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// Remaining Program.cs code omitted for brevity
När föregående kod körs i utvecklingsmiljön:
- 
              CustomExceptionHandleranropas först för att hantera ett undantag.
- Efter att ha loggat undantaget returnerar TryHandleAsync-metodenfalse, så visas undantagssidan för utvecklare.
I andra miljöer:
- 
              CustomExceptionHandleranropas först för att hantera ett undantag.
- När du har loggat undantaget returnerar TryHandleAsync-metodenfalse, så/Error-sidan visas.
UseStatusCodePages
Som standard tillhandahåller en ASP.NET Core-app inte någon statuskodsida för HTTP-felstatuskoder, till exempel 404 – Hittades inte. När appen anger en HTTP 400-599-felstatuskod som inte har någon brödtext returneras statuskoden och en tom svarstext. Om du vill aktivera standardhanterare med endast text för vanliga felstatuskoder anropar du UseStatusCodePages i Program.cs:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages();
Anropa UseStatusCodePages innan du begär hantering av mellanprogram. Anropa till exempel UseStatusCodePages före mellanskiktet för statiska filer och mellanskiktet för slutpunkter.
När UseStatusCodePages inte används returnerar navigering till en URL utan en slutpunkt ett webbläsarberoende felmeddelande som anger att slutpunkten inte kan hittas. När UseStatusCodePages anropas returnerar webbläsaren följande svar:
Status Code: 404; Not Found
              UseStatusCodePages används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
Note
Mellanprogrammet för statuskodsidor gör inte fånga undantag. Om du vill ange en anpassad felhanteringssida använder du sidan undantagshanterare.
Använd UseStatusCodePages med formatsträng
Om du vill anpassa svarsinnehållstypen och texten använder du överlagringen av UseStatusCodePages som tar en innehållstyp och formatsträng:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
I föregående kod är {0} en platshållare för felkoden.
              UseStatusCodePages med en formatsträng används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePages med lambda
Om du vill ange anpassad felhanterings- och svarsskrivningskod, använd en överlagring av UseStatusCodePages som tar ett lambda-uttryck:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
    // using static System.Net.Mime.MediaTypeNames;
    statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
    await statusCodeContext.HttpContext.Response.WriteAsync(
        $"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
              UseStatusCodePages med en lambda används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects utökningsmetod:
- Skickar en 302 – hittad statuskod till klienten.
- Omdirigerar klienten till slutpunkten för felhantering som anges i URL-mallen. Slutpunkten för felhantering visar vanligtvis felinformation och returnerar HTTP 200.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL-mallen kan innehålla en {0} platshållare för statuskoden, enligt föregående kod. Om URL-mallen börjar med ~ (tilde) ersätts ~ av appens PathBase. När du anger en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen:
- Ska omdirigera klienten till en annan slutpunkt, vanligtvis i fall där en annan app bearbetar felet. För webbappar återspeglar klientens webbläsaradressfält den omdirigerade slutpunkten.
- Bör inte bevara och returnera den ursprungliga statuskoden med det första omdirigeringssvaret.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute utökningsmetod:
- Genererar svarstextens innehåll genom att köra begärandepipelinen igen med hjälp av en alternativ sökväg.
- Ändrar inte statuskoden före eller efter att pipelinen körts om.
Den nya pipelinekörningen kan ändra svarets statuskod eftersom den nya pipelinen har fullständig kontroll över statuskoden. Om den nya pipelinen inte ändrar statuskoden skickas den ursprungliga statuskoden till klienten.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Om en slutpunkt i appen har angetts skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen ska:
- Bearbeta begäran utan att omdirigera till en annan slutpunkt. För webbappar återspeglar klientens webbläsaradressfält den ursprungligen begärda slutpunkten.
- Bevara och returnera den ursprungliga statuskoden med svaret.
URL-mallen måste börja med / och kan innehålla en platshållare {0} för statuskoden. Skicka statuskoden som en frågesträngsparameter genom att skicka ett andra argument till UseStatusCodePagesWithReExecute. Till exempel:
var app = builder.Build();  
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Slutpunkten som bearbetar felet kan hämta den ursprungliga URL:en som genererade felet, enligt följande exempel:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
    public int OriginalStatusCode { get; set; }
    public string? OriginalPathAndQuery { get; set; }
    public void OnGet(int statusCode)
    {
        OriginalStatusCode = statusCode;
        var statusCodeReExecuteFeature =
            HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
        if (statusCodeReExecuteFeature is not null)
        {
            OriginalPathAndQuery = $"{statusCodeReExecuteFeature.OriginalPathBase}"
                                    + $"{statusCodeReExecuteFeature.OriginalPath}"
                                    + $"{statusCodeReExecuteFeature.OriginalQueryString}";
        }
    }
}
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- Begränsade tjänster förblir desamma.
Inaktivera statuskodsidor
Om du vill inaktivera statuskodsidor för en MVC-kontrollant eller åtgärdsmetod använder du attributet [SkipStatusCodePages].
Om du vill inaktivera statuskodsidor för specifika begäranden i en Razor Pages-hanteringsmetod eller i en MVC-styrenhet använder du IStatusCodePagesFeature:
public void OnGet()
{
    var statusCodePagesFeature =
        HttpContext.Features.Get<IStatusCodePagesFeature>();
    if (statusCodePagesFeature is not null)
    {
        statusCodePagesFeature.Enabled = false;
    }
}
Kod för undantagshantering
Kod i undantagshanteringssidor kan också utlösa undantag. Sidor med produktionsfel bör testas noggrant och vara extra noggranna för att undvika egna undantag.
Svarsrubriker
När rubrikerna för ett svar har skickats:
- Appen kan inte ändra svarets statuskod.
- Undantagssidor eller hanterare kan inte köras. Svaret måste slutföras eller så avbryts anslutningen.
Hantering av serverfel
Förutom logiken för undantagshantering i en app kan HTTP-serverimplementering hantera vissa undantag. Om servern upptäcker ett undantag innan svarshuvuden skickas skickar servern ett 500 - Internal Server Error svar utan svarstext. Om servern får ett undantag efter att svarsrubriker har skickats, stänger servern anslutningen. Begäranden som inte hanteras av appen hanteras av servern. Alla undantag som inträffar när servern hanterar begäran hanteras av serverns undantagshantering. Appens anpassade felsidor, undantagshantering av mellanprogram och filter påverkar inte det här beteendet.
Undantagshantering vid start
Endast värdlagret kan hantera undantag som sker under appstarten. Värden kan konfigureras för att fånga startfel och fånga detaljerade fel.
Värdlagret kan visa en felsida för ett insamlat startfel endast om felet inträffar efter värdadress/portbindning. Om bindningen misslyckas:
- Värdlagret loggar ett kritiskt undantag.
- Dotnet-processen kraschar.
- Ingen felsida visas när HTTP-servern är Kestrel.
När du kör på IIS (eller Azure App Service) eller IIS Expressreturneras en 502.5 – Processfel av ASP.NET Core-modulen om processen inte kan starta. Mer information finns i Felsöka ASP.NET Core i Azure App Service och IIS.
Databasfelsida
Undantagsfiltret för databasutvecklare AddDatabaseDeveloperPageExceptionFilter samlar in databasrelaterade undantag som kan lösas med hjälp av Entity Framework Core-migreringar. När dessa undantag inträffar genereras ett HTML-svar med information om möjliga åtgärder för att lösa problemet. Den här sidan är endast aktiverad i utvecklingsmiljön. Följande kod lägger till undantagsfiltret för databasutvecklarens sida:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Undantagsfilter
I MVC-appar kan undantagsfilter konfigureras globalt eller per kontrollant eller per åtgärd. I Razor Pages-appar kan de konfigureras globalt eller per sidmodell. Dessa filter hanterar alla ohanterade undantag som inträffar under exekveringen av en controlleråtgärd eller ett annat filter. Mer information finns i filter i ASP.NET Core.
Undantagsfilter är användbara för att fånga undantag som inträffar inom MVC-action, men de är inte lika flexibla som den inbyggda undantagshantermellanvara, UseExceptionHandler. Vi rekommenderar att du använder UseExceptionHandler, såvida du inte behöver utföra felhantering på olika sätt baserat på vilken MVC-åtgärd som väljs.
Modelltillståndsfel
Information om hur du hanterar modelltillståndsfel finns i Modellbindning och modellverifiering.
Probleminformation
Probleminformation är inte det enda svarsformatet som beskriver ett HTTP API-fel, men de används ofta för att rapportera fel för HTTP-API:er.
Tjänsten probleminformation implementerar IProblemDetailsService-gränssnittet, som har stöd för att skapa probleminformation i ASP.NET Core. 
              AddProblemDetails(IServiceCollection)-tilläggsmetoden på IServiceCollection registrerar standardimplementeringen IProblemDetailsService.
I ASP.NET Core-appar genererar följande mellanprogramvara HTTP-svar med probleminformation när AddProblemDetails anropas, förutom när HTTP-huvudet för Accept-begäran inte innehåller någon av de innehållstyper som stöds av den registrerade IProblemDetailsWriter (standard: application/json):
- ExceptionHandlerMiddleware: Genererar ett probleminformationssvar när en anpassad hanterare inte har definierats.
- StatusCodePagesMiddleware: Genererar ett probleminformationssvar som standard.
- 
              DeveloperExceptionPageMiddleware: Genererar ett probleminformationssvar under utveckling när HTTP-huvudet för Acceptbegäran inte innehållertext/html.
Följande kod konfigurerar appen för att generera ett probleminformationssvar för alla HTTP-klient- och serverfelsvar som inte har brödtextinnehåll ännu:
builder.Services.AddProblemDetails();
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
I nästa avsnitt visas hur du anpassar svarstexten för probleminformation.
Anpassa probleminformation
Automatisk skapande av en ProblemDetails kan anpassas med något av följande alternativ:
- Använd ProblemDetailsOptions.CustomizeProblemDetails
- Använd en anpassad IProblemDetailsWriter
- Anropa IProblemDetailsServicei ett mellanprogram
              CustomizeProblemDetails åtgärd
Den genererade probleminformationen kan anpassas med hjälp av CustomizeProblemDetailsoch anpassningarna tillämpas på all probleminformation som genereras automatiskt.
Följande kod använder ProblemDetailsOptions för att ange CustomizeProblemDetails:
builder.Services.AddProblemDetails(options =>
    options.CustomizeProblemDetails = ctx =>
            ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName));
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
Ett HTTP Status 400 Bad Request slutpunktsresultat skapar till exempel följande svarstext för probleminformation:
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "Bad Request",
  "status": 400,
  "nodeId": "my-machine-name"
}
Anpassad IProblemDetailsWriter
En IProblemDetailsWriter implementering kan skapas för avancerade anpassningar.
public class SampleProblemDetailsWriter : IProblemDetailsWriter
{
    // Indicates that only responses with StatusCode == 400
    // are handled by this writer. All others are
    // handled by different registered writers if available.
    public bool CanWrite(ProblemDetailsContext context)
        => context.HttpContext.Response.StatusCode == 400;
    public ValueTask WriteAsync(ProblemDetailsContext context)
    {
        // Additional customizations.
        // Write to the response.
        var response = context.HttpContext.Response;
        return new ValueTask(response.WriteAsJsonAsync(context.ProblemDetails));
    }
}
              
              Obs! När du använder en anpassad IProblemDetailsWritermåste den anpassade IProblemDetailsWriter registreras innan du anropar AddRazorPages, AddControllers, AddControllersWithViewseller AddMvc:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IProblemDetailsWriter, SampleProblemDetailsWriter>();
var app = builder.Build();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsWriter>() is
            { } problemDetailsService)
        {
            if (problemDetailsService.CanWrite(new ProblemDetailsContext() { HttpContext = context }))
            {
                (string Detail, string Type) details = mathErrorFeature.MathError switch
                {
                    MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                        "https://en.wikipedia.org/wiki/Division_by_zero"),
                    _ => ("Negative or complex numbers are not valid input.",
                        "https://en.wikipedia.org/wiki/Square_root")
                };
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                    {
                        Title = "Bad Input",
                        Detail = details.Detail,
                        Type = details.Type
                    }
                });
            }
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.DivisionByZeroError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.NegativeRadicandError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.Run();
Probleminformation från Middleware
Ett annat sätt att använda ProblemDetailsOptions med CustomizeProblemDetails är att ange ProblemDetails i mellanprogram. Ett probleminformationssvar kan skrivas genom att anropa IProblemDetailsService.WriteAsync:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsService>() is
                                                           { } problemDetailsService)
        {
            (string Detail, string Type) details = mathErrorFeature.MathError switch
            {
                MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                "https://en.wikipedia.org/wiki/Division_by_zero"),
                _ => ("Negative or complex numbers are not valid input.", 
                "https://en.wikipedia.org/wiki/Square_root")
            };
            await problemDetailsService.WriteAsync(new ProblemDetailsContext
            {
                HttpContext = context,
                ProblemDetails =
                {
                    Title = "Bad Input",
                    Detail = details.Detail,
                    Type = details.Type
                }
            });
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.DivisionByZeroError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.NegativeRadicandError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.MapControllers();
app.Run();
I föregående kod returnerar de minimala API-slutpunkterna /divide och /squareroot det förväntade anpassade problemsvaret vid felindata.
API-kontrollantens slutpunkter returnerar standardfelsvaret vid felindata, inte det anpassade problemsvaret. Standardproblemsvaret returneras eftersom API-kontrollanten har skrivit till svarsströmmen Probleminformation för felstatuskoderinnan IProblemDetailsService.WriteAsync anropas och svaret inte skrivs igen.
Följande ValuesController returnerar BadRequestResult, vilket skriver till svarsströmmen och därför förhindrar att ett anpassat problemsvar returneras.
[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // /api/values/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Följande Values3Controller returnerar ControllerBase.Problem så att det förväntade anpassade problemresultatet returneras:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values3Controller : ControllerBase
{
    // /api/values3/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Divison by zero is not defined.",
                type: "https://en.wikipedia.org/wiki/Division_by_zero",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values3/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Negative or complex numbers are not valid input.",
                type: "https://en.wikipedia.org/wiki/Square_root",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Skapa en ProblemDetails-last för undantag
Tänk på följande app:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
app.MapControllers();
app.Run();
När ett undantag inträffar i icke-utvecklingsmiljöer är följande ett standardsvar ProblemDetails som returneras till klienten:
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title":"An error occurred while processing your request.",
"status":500,"traceId":"00-b644<snip>-00"
}
För de flesta appar är föregående kod allt som behövs för undantag. I följande avsnitt visas dock hur du får mer detaljerade problemsvar.
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet och skriva ett probleminformationssvar med IProblemDetailsService.WriteAsync:
using Microsoft.AspNetCore.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = Text.Plain;
            var title = "Bad Input";
            var detail = "Invalid input";
            var type = "https://errors.example.com/badInput";
            if (context.RequestServices.GetService<IProblemDetailsService>() is
                { } problemDetailsService)
            {
                var exceptionHandlerFeature =
               context.Features.Get<IExceptionHandlerFeature>();
                var exceptionType = exceptionHandlerFeature?.Error;
                if (exceptionType != null &&
                   exceptionType.Message.Contains("infinity"))
                {
                    title = "Argument exception";
                    detail = "Invalid input";
                    type = "https://errors.example.com/argumentException";
                }
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                {
                    Title = title,
                    Detail = detail,
                    Type = type
                }
                });
            }
        });
    });
}
app.MapControllers();
app.Run();
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
En annan metod för att generera probleminformation är att använda NuGet-paketet från tredje part Hellang.Middleware.ProblemDetails som kan användas för att mappa undantag och klientfel till probleminformation.
Ytterligare resurser
Av Tom Dykstra
Den här artikeln beskriver vanliga metoder för att hantera fel i ASP.NET Core-webbappar. Se även Hantera fel i ASP.NET Core-API:er.
Undantagssida för utvecklare
undantagssidan för utvecklare visar detaljerad information om ohanterade undantag för begäranden. ASP.NET Core-appar aktiverar utvecklarens undantagssida som standard när båda:
- Kör i utvecklingsmiljö .
- App som skapats med de aktuella mallarna, d.v.s. med hjälp av WebApplication.CreateBuilder.  Appar som skapats med hjälp av WebHost.CreateDefaultBuildermåste aktivera undantagssidan för utvecklare genom att anropaapp.UseDeveloperExceptionPageiConfigure.
Undantagssidan för utvecklare körs tidigt i middleware-pipelinen, så att den kan fånga ohanterade undantag som genereras i efterföljande mellanprogram.
Detaljerad undantagsinformation bör inte visas offentligt när appen körs i produktionsmiljön. Mer information om hur du konfigurerar miljöer finns i ASP.NET Core Runtime-miljöer.
Sidan Undantag för utvecklare kan innehålla följande information om undantaget och begäran:
- Stackspårning
- Frågesträngsparametrar, om några
- Cookies, om några
- Headers
Undantagssidan för utvecklare är inte garanterad att ange någon information. Använd logg för fullständig felinformation.
Undantagshanteringsida
Om du vill konfigurera en anpassad felhanteringssida för Produktionsmiljöanropar du UseExceptionHandler. Denna undantagshanterande mellanprogramvara:
- Fångar upp och loggar ohanterade undantag.
- Utför begäran på nytt i en alternativ pipeline med den angivna sökvägen. Begäran utförs inte igen om svaret redan har påbörjats. Den mallgenererade koden kör begäran igen med hjälp av sökvägen /Error.
Warning
Om den alternativa pipelinen genererar ett eget undantag, överväxlar Undantagshantering mellanprogram det ursprungliga undantaget.
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- För den UseExceptionHandler(IApplicationBuilder, String)-överbelastning som används i mallar ändras endast begärans sökväg och routdata rensas. Begärdata, såsom rubriker, metod och objekt, återanvänds alla som de är.
- Begränsade tjänster förblir desamma.
I följande exempel lägger UseExceptionHandler till undantagshanteringsmellanprogram i miljöer som inte är utvecklingsmiljöer:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Appmallen Razor Pages innehåller en felsida (.cshtml) och PageModel -klass (ErrorModel) i mappen Pages. För en MVC-app innehåller projektmallen en Error-åtgärdsmetod och en felvy för den Home kontrollanten.
Undantagshanteringsmellanprogrammet kör begäran igen med hjälp av den ursprungliga HTTP-metoden. Om en slutpunkt för felhanterare är begränsad till en specifik uppsättning HTTP-metoder körs den endast för dessa HTTP-metoder. Till exempel körs en MVC-kontrollantåtgärd som använder attributet [HttpGet] endast för GET-begäranden. För att säkerställa att alla begäranden når sidan för anpassad felhantering ska du inte begränsa dem till en specifik uppsättning HTTP-metoder.
Så här hanterar du undantag på olika sätt baserat på den ursprungliga HTTP-metoden:
- Skapa flera hanteringsmetoder för Razor Pages. Använd till exempel OnGetför att hantera GET-undantag och användaOnPostför att hantera POST-undantag.
- För MVC använder du HTTP-verbattribut på flera åtgärder. Använd till exempel [HttpGet]för att hantera GET-undantag och använda[HttpPost]för att hantera POST-undantag.
Om du vill tillåta oautentiserade användare att visa sidan för anpassad felhantering kontrollerar du att den stöder anonym åtkomst.
Få åtkomst till undantaget
Använd IExceptionHandlerPathFeature för att komma åt undantaget och den ursprungliga sökvägen för begäran i en felhanterare. I följande exempel används IExceptionHandlerPathFeature för att få mer information om undantaget som utlöstes:
[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; }
    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        var exceptionHandlerPathFeature =
            HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "The file was not found.";
        }
        if (exceptionHandlerPathFeature?.Path == "/")
        {
            ExceptionMessage ??= string.Empty;
            ExceptionMessage += " Page: Home.";
        }
    }
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
Lambda för undantagshanterare
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet innan svaret returneras.
Följande kod använder en lambda för undantagshantering:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;
            await context.Response.WriteAsync("An exception was thrown.");
            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();
            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync(" The file was not found.");
            }
            if (exceptionHandlerPathFeature?.Path == "/")
            {
                await context.Response.WriteAsync(" Page: Home.");
            }
        });
    });
    app.UseHsts();
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
IExceptionHandler
IExceptionHandler är ett gränssnitt som ger utvecklaren ett återanrop för att hantera kända undantag på en central plats.
              IExceptionHandler implementeringar registreras genom att anropa IServiceCollection.AddExceptionHandler<T> [IServiceCollection.AddExceptionHandler<T>]. Livslängden för en IExceptionHandler instans är singleton. Flera implementeringar kan läggas till och de anropas i den registrerade ordningen.
Om en undantagshanterare hanterar en begäran kan den returnera true för att stoppa bearbetningen. Om ett undantag inte hanteras av någon undantagshanterare återgår kontrollen till standardbeteendet och alternativen från mellanprogrammet. Olika mått och loggar genereras för hanterade och ohanterade undantag.
I följande exempel visas en IExceptionHandler implementering:
using Microsoft.AspNetCore.Diagnostics;
namespace ErrorHandlingSample
{
    public class CustomExceptionHandler : IExceptionHandler
    {
        private readonly ILogger<CustomExceptionHandler> logger;
        public CustomExceptionHandler(ILogger<CustomExceptionHandler> logger)
        {
            this.logger = logger;
        }
        public ValueTask<bool> TryHandleAsync(
            HttpContext httpContext,
            Exception exception,
            CancellationToken cancellationToken)
        {
            var exceptionMessage = exception.Message;
            logger.LogError(
                "Error Message: {exceptionMessage}, Time of occurrence {time}",
                exceptionMessage, DateTime.UtcNow);
            // Return false to continue with the default behavior
            // - or - return true to signal that this exception is handled
            return ValueTask.FromResult(false);
        }
    }
}
I följande exempel visas hur du registrerar en IExceptionHandler implementering för beroendeinmatning:
using ErrorHandlingSample;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
builder.Services.AddExceptionHandler<CustomExceptionHandler>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// Remaining Program.cs code omitted for brevity
När föregående kod körs i utvecklingsmiljön:
- 
              CustomExceptionHandleranropas först för att hantera ett undantag.
- Efter att ha loggat undantaget returnerar TryHandleException-metodenfalse, så visas undantagssidan för utvecklare.
I andra miljöer:
- 
              CustomExceptionHandleranropas först för att hantera ett undantag.
- När du har loggat undantaget returnerar TryHandleException-metodenfalse, så/Error-sidan visas.
UseStatusCodePages
Som standard tillhandahåller en ASP.NET Core-app inte någon statuskodsida för HTTP-felstatuskoder, till exempel 404 – Hittades inte. När appen anger en HTTP 400-599-felstatuskod som inte har någon brödtext returneras statuskoden och en tom svarstext. Om du vill aktivera standardhanterare med endast text för vanliga felstatuskoder anropar du UseStatusCodePages i Program.cs:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages();
Anropa UseStatusCodePages innan du begär hantering av mellanprogram. Anropa till exempel UseStatusCodePages före mellanskiktet för statiska filer och mellanskiktet för slutpunkter.
När UseStatusCodePages inte används returnerar navigering till en URL utan en slutpunkt ett webbläsarberoende felmeddelande som anger att slutpunkten inte kan hittas. När UseStatusCodePages anropas returnerar webbläsaren följande svar:
Status Code: 404; Not Found
              UseStatusCodePages används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
Note
Mellanprogrammet för statuskodsidor gör inte fånga undantag. Om du vill ange en anpassad felhanteringssida använder du sidan undantagshanterare.
Använd UseStatusCodePages med formatsträng
Om du vill anpassa svarsinnehållstypen och texten använder du överlagringen av UseStatusCodePages som tar en innehållstyp och formatsträng:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
I föregående kod är {0} en platshållare för felkoden.
              UseStatusCodePages med en formatsträng används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePages med lambda
Om du vill ange anpassad felhanterings- och svarsskrivningskod, använd en överlagring av UseStatusCodePages som tar ett lambda-uttryck:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
    // using static System.Net.Mime.MediaTypeNames;
    statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
    await statusCodeContext.HttpContext.Response.WriteAsync(
        $"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
              UseStatusCodePages med en lambda används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects utökningsmetod:
- Skickar en 302 – hittad statuskod till klienten.
- Omdirigerar klienten till slutpunkten för felhantering som anges i URL-mallen. Slutpunkten för felhantering visar vanligtvis felinformation och returnerar HTTP 200.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL-mallen kan innehålla en {0} platshållare för statuskoden, enligt föregående kod. Om URL-mallen börjar med ~ (tilde) ersätts ~ av appens PathBase. När du anger en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen:
- Ska omdirigera klienten till en annan slutpunkt, vanligtvis i fall där en annan app bearbetar felet. För webbappar återspeglar klientens webbläsaradressfält den omdirigerade slutpunkten.
- Bör inte bevara och returnera den ursprungliga statuskoden med det första omdirigeringssvaret.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute utökningsmetod:
- Genererar svarstextens innehåll genom att köra begärandepipelinen igen med hjälp av en alternativ sökväg.
- Ändrar inte statuskoden före eller efter att pipelinen körts om.
Den nya pipelinekörningen kan ändra svarets statuskod eftersom den nya pipelinen har fullständig kontroll över statuskoden. Om den nya pipelinen inte ändrar statuskoden skickas den ursprungliga statuskoden till klienten.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Om en slutpunkt i appen har angetts skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen ska:
- Bearbeta begäran utan att omdirigera till en annan slutpunkt. För webbappar återspeglar klientens webbläsaradressfält den ursprungligen begärda slutpunkten.
- Bevara och returnera den ursprungliga statuskoden med svaret.
URL-mallen måste börja med / och kan innehålla en platshållare {0} för statuskoden. Skicka statuskoden som en frågesträngsparameter genom att skicka ett andra argument till UseStatusCodePagesWithReExecute. Till exempel:
var app = builder.Build();  
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Slutpunkten som bearbetar felet kan hämta den ursprungliga URL:en som genererade felet, enligt följande exempel:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
    public int OriginalStatusCode { get; set; }
    public string? OriginalPathAndQuery { get; set; }
    public void OnGet(int statusCode)
    {
        OriginalStatusCode = statusCode;
        var statusCodeReExecuteFeature =
            HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
        if (statusCodeReExecuteFeature is not null)
        {
            OriginalPathAndQuery = $"{statusCodeReExecuteFeature.OriginalPathBase}"
                                    + $"{statusCodeReExecuteFeature.OriginalPath}"
                                    + $"{statusCodeReExecuteFeature.OriginalQueryString}";
        }
    }
}
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- Begränsade tjänster förblir desamma.
Inaktivera statuskodsidor
Om du vill inaktivera statuskodsidor för en MVC-kontrollant eller åtgärdsmetod använder du attributet [SkipStatusCodePages].
Om du vill inaktivera statuskodsidor för specifika begäranden i en Razor Pages-hanteringsmetod eller i en MVC-styrenhet använder du IStatusCodePagesFeature:
public void OnGet()
{
    var statusCodePagesFeature =
        HttpContext.Features.Get<IStatusCodePagesFeature>();
    if (statusCodePagesFeature is not null)
    {
        statusCodePagesFeature.Enabled = false;
    }
}
Kod för undantagshantering
Kod i undantagshanteringssidor kan också utlösa undantag. Sidor med produktionsfel bör testas noggrant och vara extra noggranna för att undvika egna undantag.
Svarsrubriker
När rubrikerna för ett svar har skickats:
- Appen kan inte ändra svarets statuskod.
- Undantagssidor eller hanterare kan inte köras. Svaret måste slutföras eller så avbryts anslutningen.
Hantering av serverfel
Förutom logiken för undantagshantering i en app kan HTTP-serverimplementering hantera vissa undantag. Om servern upptäcker ett undantag innan svarshuvuden skickas skickar servern ett 500 - Internal Server Error svar utan svarstext. Om servern får ett undantag efter att svarsrubriker har skickats, stänger servern anslutningen. Begäranden som inte hanteras av appen hanteras av servern. Alla undantag som inträffar när servern hanterar begäran hanteras av serverns undantagshantering. Appens anpassade felsidor, undantagshantering av mellanprogram och filter påverkar inte det här beteendet.
Undantagshantering vid start
Endast värdlagret kan hantera undantag som sker under appstarten. Värden kan konfigureras för att fånga startfel och fånga detaljerade fel.
Värdlagret kan visa en felsida för ett insamlat startfel endast om felet inträffar efter värdadress/portbindning. Om bindningen misslyckas:
- Värdlagret loggar ett kritiskt undantag.
- Dotnet-processen kraschar.
- Ingen felsida visas när HTTP-servern är Kestrel.
När du kör på IIS (eller Azure App Service) eller IIS Expressreturneras en 502.5 – Processfel av ASP.NET Core-modulen om processen inte kan starta. Mer information finns i Felsöka ASP.NET Core i Azure App Service och IIS.
Databasfelsida
Undantagsfiltret för databasutvecklare AddDatabaseDeveloperPageExceptionFilter samlar in databasrelaterade undantag som kan lösas med hjälp av Entity Framework Core-migreringar. När dessa undantag inträffar genereras ett HTML-svar med information om möjliga åtgärder för att lösa problemet. Den här sidan är endast aktiverad i utvecklingsmiljön. Följande kod lägger till undantagsfiltret för databasutvecklarens sida:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Undantagsfilter
I MVC-appar kan undantagsfilter konfigureras globalt eller per kontrollant eller per åtgärd. I Razor Pages-appar kan de konfigureras globalt eller per sidmodell. Dessa filter hanterar alla ohanterade undantag som inträffar under exekveringen av en controlleråtgärd eller ett annat filter. Mer information finns i filter i ASP.NET Core.
Undantagsfilter är användbara för att fånga undantag som inträffar inom MVC-action, men de är inte lika flexibla som den inbyggda undantagshantermellanvara, UseExceptionHandler. Vi rekommenderar att du använder UseExceptionHandler, såvida du inte behöver utföra felhantering på olika sätt baserat på vilken MVC-åtgärd som väljs.
Modelltillståndsfel
Information om hur du hanterar modelltillståndsfel finns i Modellbindning och modellverifiering.
Probleminformation
Probleminformation är inte det enda svarsformatet som beskriver ett HTTP API-fel, men de används ofta för att rapportera fel för HTTP-API:er.
Tjänsten probleminformation implementerar IProblemDetailsService-gränssnittet, som har stöd för att skapa probleminformation i ASP.NET Core. 
              AddProblemDetails(IServiceCollection)-tilläggsmetoden på IServiceCollection registrerar standardimplementeringen IProblemDetailsService.
I ASP.NET Core-appar genererar följande mellanprogramvara HTTP-svar med probleminformation när AddProblemDetails anropas, förutom när HTTP-huvudet för Accept-begäran inte innehåller någon av de innehållstyper som stöds av den registrerade IProblemDetailsWriter (standard: application/json):
- ExceptionHandlerMiddleware: Genererar ett probleminformationssvar när en anpassad hanterare inte har definierats.
- StatusCodePagesMiddleware: Genererar ett probleminformationssvar som standard.
- 
              DeveloperExceptionPageMiddleware: Genererar ett probleminformationssvar under utveckling när HTTP-huvudet för Acceptbegäran inte innehållertext/html.
Följande kod konfigurerar appen för att generera ett probleminformationssvar för alla HTTP-klient- och serverfelsvar som inte har något brödtextinnehåll ännu:
builder.Services.AddProblemDetails();
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
I nästa avsnitt visas hur du anpassar svarstexten för probleminformation.
Anpassa probleminformation
Automatisk skapande av en ProblemDetails kan anpassas med något av följande alternativ:
- Använd ProblemDetailsOptions.CustomizeProblemDetails
- Använd en anpassad IProblemDetailsWriter
- Anropa IProblemDetailsServicei ett mellanprogram
              CustomizeProblemDetails åtgärd
Den genererade probleminformationen kan anpassas med hjälp av CustomizeProblemDetailsoch anpassningarna tillämpas på all probleminformation som genereras automatiskt.
Följande kod använder ProblemDetailsOptions för att ange CustomizeProblemDetails:
builder.Services.AddProblemDetails(options =>
    options.CustomizeProblemDetails = ctx =>
            ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName));
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
Ett HTTP Status 400 Bad Request slutpunktsresultat skapar till exempel följande svarstext för probleminformation:
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "Bad Request",
  "status": 400,
  "nodeId": "my-machine-name"
}
Anpassad IProblemDetailsWriter
En IProblemDetailsWriter implementering kan skapas för avancerade anpassningar.
public class SampleProblemDetailsWriter : IProblemDetailsWriter
{
    // Indicates that only responses with StatusCode == 400
    // are handled by this writer. All others are
    // handled by different registered writers if available.
    public bool CanWrite(ProblemDetailsContext context)
        => context.HttpContext.Response.StatusCode == 400;
    public ValueTask WriteAsync(ProblemDetailsContext context)
    {
        // Additional customizations.
        // Write to the response.
        var response = context.HttpContext.Response;
        return new ValueTask(response.WriteAsJsonAsync(context.ProblemDetails));
    }
}
              
              Obs! När du använder en anpassad IProblemDetailsWritermåste den anpassade IProblemDetailsWriter registreras innan du anropar AddRazorPages, AddControllers, AddControllersWithViewseller AddMvc:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IProblemDetailsWriter, SampleProblemDetailsWriter>();
var app = builder.Build();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsWriter>() is
            { } problemDetailsService)
        {
            if (problemDetailsService.CanWrite(new ProblemDetailsContext() { HttpContext = context }))
            {
                (string Detail, string Type) details = mathErrorFeature.MathError switch
                {
                    MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                        "https://en.wikipedia.org/wiki/Division_by_zero"),
                    _ => ("Negative or complex numbers are not valid input.",
                        "https://en.wikipedia.org/wiki/Square_root")
                };
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                    {
                        Title = "Bad Input",
                        Detail = details.Detail,
                        Type = details.Type
                    }
                });
            }
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.DivisionByZeroError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.NegativeRadicandError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.Run();
Probleminformation från Middleware
Ett annat sätt att använda ProblemDetailsOptions med CustomizeProblemDetails är att ange ProblemDetails i mellanprogram. Ett probleminformationssvar kan skrivas genom att anropa IProblemDetailsService.WriteAsync:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsService>() is
                                                           { } problemDetailsService)
        {
            (string Detail, string Type) details = mathErrorFeature.MathError switch
            {
                MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                "https://en.wikipedia.org/wiki/Division_by_zero"),
                _ => ("Negative or complex numbers are not valid input.", 
                "https://en.wikipedia.org/wiki/Square_root")
            };
            await problemDetailsService.WriteAsync(new ProblemDetailsContext
            {
                HttpContext = context,
                ProblemDetails =
                {
                    Title = "Bad Input",
                    Detail = details.Detail,
                    Type = details.Type
                }
            });
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.DivisionByZeroError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.NegativeRadicandError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.MapControllers();
app.Run();
I föregående kod returnerar de minimala API-slutpunkterna /divide och /squareroot det förväntade anpassade problemsvaret vid felindata.
API-kontrollantens slutpunkter returnerar standardfelsvaret vid felindata, inte det anpassade problemsvaret. Standardproblemsvaret returneras eftersom API-kontrollanten har skrivit till svarsströmmen Probleminformation för felstatuskoderinnan IProblemDetailsService.WriteAsync anropas och svaret inte skrivs igen.
Följande ValuesController returnerar BadRequestResult, vilket skriver till svarsströmmen och därför förhindrar att ett anpassat problemsvar returneras.
[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // /api/values/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Följande Values3Controller returnerar ControllerBase.Problem så att det förväntade anpassade problemresultatet returneras:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values3Controller : ControllerBase
{
    // /api/values3/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Divison by zero is not defined.",
                type: "https://en.wikipedia.org/wiki/Division_by_zero",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values3/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Negative or complex numbers are not valid input.",
                type: "https://en.wikipedia.org/wiki/Square_root",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Skapa en ProblemDetails-last för undantag
Tänk på följande app:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
app.MapControllers();
app.Run();
När ett undantag inträffar i icke-utvecklingsmiljöer är följande ett standardsvar ProblemDetails som returneras till klienten:
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title":"An error occurred while processing your request.",
"status":500,"traceId":"00-b644<snip>-00"
}
För de flesta appar är föregående kod allt som behövs för undantag. I följande avsnitt visas dock hur du får mer detaljerade problemsvar.
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet och skriva ett probleminformationssvar med IProblemDetailsService.WriteAsync:
using Microsoft.AspNetCore.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = Text.Plain;
            var title = "Bad Input";
            var detail = "Invalid input";
            var type = "https://errors.example.com/badInput";
            if (context.RequestServices.GetService<IProblemDetailsService>() is
                { } problemDetailsService)
            {
                var exceptionHandlerFeature =
               context.Features.Get<IExceptionHandlerFeature>();
                var exceptionType = exceptionHandlerFeature?.Error;
                if (exceptionType != null &&
                   exceptionType.Message.Contains("infinity"))
                {
                    title = "Argument exception";
                    detail = "Invalid input";
                    type = "https://errors.example.com/argumentException";
                }
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                {
                    Title = title,
                    Detail = detail,
                    Type = type
                }
                });
            }
        });
    });
}
app.MapControllers();
app.Run();
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
En annan metod för att generera probleminformation är att använda NuGet-paketet från tredje part Hellang.Middleware.ProblemDetails som kan användas för att mappa undantag och klientfel till probleminformation.
Ytterligare resurser
Av Tom Dykstra
Den här artikeln beskriver vanliga metoder för att hantera fel i ASP.NET Core-webbappar. Se även Hantera fel i ASP.NET Core-API:er.
Undantagssida för utvecklare
undantagssidan för utvecklare visar detaljerad information om ohanterade undantag för begäranden. ASP.NET Core-appar aktiverar utvecklarens undantagssida som standard när båda:
- Kör i utvecklingsmiljö .
- App som skapats med de aktuella mallarna, d.v.s. med hjälp av WebApplication.CreateBuilder.  Appar som skapats med hjälp av WebHost.CreateDefaultBuildermåste aktivera undantagssidan för utvecklare genom att anropaapp.UseDeveloperExceptionPageiConfigure.
Undantagssidan för utvecklare körs tidigt i middleware-pipelinen, så att den kan fånga ohanterade undantag som genereras i efterföljande mellanprogram.
Detaljerad undantagsinformation bör inte visas offentligt när appen körs i produktionsmiljön. Mer information om hur du konfigurerar miljöer finns i ASP.NET Core Runtime-miljöer.
Sidan Undantag för utvecklare kan innehålla följande information om undantaget och begäran:
- Stackspårning
- Frågesträngsparametrar, om några
- Cookies, om några
- Headers
Undantagssidan för utvecklare är inte garanterad att ange någon information. Använd logg för fullständig felinformation.
Undantagshanteringsida
Om du vill konfigurera en anpassad felhanteringssida för Produktionsmiljöanropar du UseExceptionHandler. Denna undantagshanterande mellanprogramvara:
- Fångar upp och loggar ohanterade undantag.
- Utför begäran på nytt i en alternativ pipeline med den angivna sökvägen. Begäran utförs inte igen om svaret redan har påbörjats. Den mallgenererade koden kör begäran igen med hjälp av sökvägen /Error.
Warning
Om den alternativa pipelinen genererar ett eget undantag, överväxlar Undantagshantering mellanprogram det ursprungliga undantaget.
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- För den UseExceptionHandler(IApplicationBuilder, String)-överbelastning som används i mallar ändras endast begärans sökväg och routdata rensas. Begärdata, såsom rubriker, metod och objekt, återanvänds alla som de är.
- Begränsade tjänster förblir desamma.
I följande exempel lägger UseExceptionHandler till undantagshanteringsmellanprogram i miljöer som inte är utvecklingsmiljöer:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Appmallen Razor Pages innehåller en felsida (.cshtml) och PageModel -klass (ErrorModel) i mappen Pages. För en MVC-app innehåller projektmallen en Error-åtgärdsmetod och en felvy för den Home kontrollanten.
Undantagshanteringsmellanprogrammet kör begäran igen med hjälp av den ursprungliga HTTP-metoden. Om en slutpunkt för felhanterare är begränsad till en specifik uppsättning HTTP-metoder körs den endast för dessa HTTP-metoder. Till exempel körs en MVC-kontrollantåtgärd som använder attributet [HttpGet] endast för GET-begäranden. För att säkerställa att alla begäranden når sidan för anpassad felhantering ska du inte begränsa dem till en specifik uppsättning HTTP-metoder.
Så här hanterar du undantag på olika sätt baserat på den ursprungliga HTTP-metoden:
- Skapa flera hanteringsmetoder för Razor Pages. Använd till exempel OnGetför att hantera GET-undantag och användaOnPostför att hantera POST-undantag.
- För MVC använder du HTTP-verbattribut på flera åtgärder. Använd till exempel [HttpGet]för att hantera GET-undantag och använda[HttpPost]för att hantera POST-undantag.
Om du vill tillåta oautentiserade användare att visa sidan för anpassad felhantering kontrollerar du att den stöder anonym åtkomst.
Få åtkomst till undantaget
Använd IExceptionHandlerPathFeature för att komma åt undantaget och den ursprungliga sökvägen för begäran i en felhanterare. I följande exempel används IExceptionHandlerPathFeature för att få mer information om undantaget som utlöstes:
[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; }
    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        var exceptionHandlerPathFeature =
            HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "The file was not found.";
        }
        if (exceptionHandlerPathFeature?.Path == "/")
        {
            ExceptionMessage ??= string.Empty;
            ExceptionMessage += " Page: Home.";
        }
    }
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
Lambda för undantagshanterare
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet innan svaret returneras.
Följande kod använder en lambda för undantagshantering:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;
            await context.Response.WriteAsync("An exception was thrown.");
            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();
            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync(" The file was not found.");
            }
            if (exceptionHandlerPathFeature?.Path == "/")
            {
                await context.Response.WriteAsync(" Page: Home.");
            }
        });
    });
    app.UseHsts();
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
UseStatusCodePages
Som standard tillhandahåller en ASP.NET Core-app inte någon statuskodsida för HTTP-felstatuskoder, till exempel 404 – Hittades inte. När appen anger en HTTP 400-599-felstatuskod som inte har någon brödtext returneras statuskoden och en tom svarstext. Om du vill aktivera standardhanterare med endast text för vanliga felstatuskoder anropar du UseStatusCodePages i Program.cs:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages();
Anropa UseStatusCodePages innan du begär hantering av mellanprogram. Anropa till exempel UseStatusCodePages före mellanskiktet för statiska filer och mellanskiktet för slutpunkter.
När UseStatusCodePages inte används returnerar navigering till en URL utan en slutpunkt ett webbläsarberoende felmeddelande som anger att slutpunkten inte kan hittas. När UseStatusCodePages anropas returnerar webbläsaren följande svar:
Status Code: 404; Not Found
              UseStatusCodePages används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
Note
Mellanprogrammet för statuskodsidor gör inte fånga undantag. Om du vill ange en anpassad felhanteringssida använder du sidan undantagshanterare.
Använd UseStatusCodePages med formatsträng
Om du vill anpassa svarsinnehållstypen och texten använder du överlagringen av UseStatusCodePages som tar en innehållstyp och formatsträng:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
I föregående kod är {0} en platshållare för felkoden.
              UseStatusCodePages med en formatsträng används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePages med lambda
Om du vill ange anpassad felhanterings- och svarsskrivningskod, använd en överlagring av UseStatusCodePages som tar ett lambda-uttryck:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
    // using static System.Net.Mime.MediaTypeNames;
    statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
    await statusCodeContext.HttpContext.Response.WriteAsync(
        $"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
              UseStatusCodePages med en lambda används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects utökningsmetod:
- Skickar en 302 – hittad statuskod till klienten.
- Omdirigerar klienten till slutpunkten för felhantering som anges i URL-mallen. Slutpunkten för felhantering visar vanligtvis felinformation och returnerar HTTP 200.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL-mallen kan innehålla en {0} platshållare för statuskoden, enligt föregående kod. Om URL-mallen börjar med ~ (tilde) ersätts ~ av appens PathBase. När du anger en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen:
- Ska omdirigera klienten till en annan slutpunkt, vanligtvis i fall där en annan app bearbetar felet. För webbappar återspeglar klientens webbläsaradressfält den omdirigerade slutpunkten.
- Bör inte bevara och returnera den ursprungliga statuskoden med det första omdirigeringssvaret.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute utökningsmetod:
- Genererar svarstextens innehåll genom att köra begärandepipelinen igen med hjälp av en alternativ sökväg.
- Ändrar inte statuskoden före eller efter att pipelinen körts om.
Den nya pipelinekörningen kan ändra svarets statuskod eftersom den nya pipelinen har fullständig kontroll över statuskoden. Om den nya pipelinen inte ändrar statuskoden skickas den ursprungliga statuskoden till klienten.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Om en slutpunkt i appen har angetts skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen ska:
- Bearbeta begäran utan att omdirigera till en annan slutpunkt. För webbappar återspeglar klientens webbläsaradressfält den ursprungligen begärda slutpunkten.
- Bevara och returnera den ursprungliga statuskoden med svaret.
URL-mallen måste börja med / och kan innehålla en platshållare {0} för statuskoden. Skicka statuskoden som en frågesträngsparameter genom att skicka ett andra argument till UseStatusCodePagesWithReExecute. Till exempel:
var app = builder.Build();  
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Slutpunkten som bearbetar felet kan hämta den ursprungliga URL:en som genererade felet, enligt följande exempel:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
    public int OriginalStatusCode { get; set; }
    public string? OriginalPathAndQuery { get; set; }
    public void OnGet(int statusCode)
    {
        OriginalStatusCode = statusCode;
        var statusCodeReExecuteFeature =
            HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
        if (statusCodeReExecuteFeature is not null)
        {
            OriginalPathAndQuery = $"{statusCodeReExecuteFeature.OriginalPathBase}"
                                    + $"{statusCodeReExecuteFeature.OriginalPath}"
                                    + $"{statusCodeReExecuteFeature.OriginalQueryString}";
        }
    }
}
Eftersom det här mellanprogrammet kan köra pipelinen för begäran igen:
- Mellanprogram måste hantera återinträde med samma begäran. Detta innebär normalt antingen att de rensar upp sitt tillstånd efter att ha anropat _nexteller cachelagrar bearbetningen påHttpContextför att undvika att göra om den. När du hanterar begärandetexten innebär detta antingen buffring eller cachelagring av resultat som formulärläsaren.
- Begränsade tjänster förblir desamma.
Inaktivera statuskodsidor
Om du vill inaktivera statuskodsidor för en MVC-kontrollant eller åtgärdsmetod använder du attributet [SkipStatusCodePages].
Om du vill inaktivera statuskodsidor för specifika begäranden i en Razor Pages-hanteringsmetod eller i en MVC-styrenhet använder du IStatusCodePagesFeature:
public void OnGet()
{
    var statusCodePagesFeature =
        HttpContext.Features.Get<IStatusCodePagesFeature>();
    if (statusCodePagesFeature is not null)
    {
        statusCodePagesFeature.Enabled = false;
    }
}
Kod för undantagshantering
Kod i undantagshanteringssidor kan också utlösa undantag. Sidor med produktionsfel bör testas noggrant och vara extra noggranna för att undvika egna undantag.
Svarsrubriker
När rubrikerna för ett svar har skickats:
- Appen kan inte ändra svarets statuskod.
- Undantagssidor eller hanterare kan inte köras. Svaret måste slutföras eller så avbryts anslutningen.
Hantering av serverfel
Förutom logiken för undantagshantering i en app kan HTTP-serverimplementering hantera vissa undantag. Om servern upptäcker ett undantag innan svarshuvuden skickas skickar servern ett 500 - Internal Server Error svar utan svarstext. Om servern får ett undantag efter att svarsrubriker har skickats, stänger servern anslutningen. Begäranden som inte hanteras av appen hanteras av servern. Alla undantag som inträffar när servern hanterar begäran hanteras av serverns undantagshantering. Appens anpassade felsidor, undantagshantering av mellanprogram och filter påverkar inte det här beteendet.
Undantagshantering vid start
Endast värdlagret kan hantera undantag som sker under appstarten. Värden kan konfigureras för att fånga startfel och fånga detaljerade fel.
Värdlagret kan visa en felsida för ett insamlat startfel endast om felet inträffar efter värdadress/portbindning. Om bindningen misslyckas:
- Värdlagret loggar ett kritiskt undantag.
- Dotnet-processen kraschar.
- Ingen felsida visas när HTTP-servern är Kestrel.
När du kör på IIS (eller Azure App Service) eller IIS Expressreturneras en 502.5 – Processfel av ASP.NET Core-modulen om processen inte kan starta. Mer information finns i Felsöka ASP.NET Core i Azure App Service och IIS.
Databasfelsida
Undantagsfiltret för databasutvecklare AddDatabaseDeveloperPageExceptionFilter samlar in databasrelaterade undantag som kan lösas med hjälp av Entity Framework Core-migreringar. När dessa undantag inträffar genereras ett HTML-svar med information om möjliga åtgärder för att lösa problemet. Den här sidan är endast aktiverad i utvecklingsmiljön. Följande kod lägger till undantagsfiltret för databasutvecklarens sida:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Undantagsfilter
I MVC-appar kan undantagsfilter konfigureras globalt eller per kontrollant eller per åtgärd. I Razor Pages-appar kan de konfigureras globalt eller per sidmodell. Dessa filter hanterar alla ohanterade undantag som inträffar under exekveringen av en controlleråtgärd eller ett annat filter. Mer information finns i filter i ASP.NET Core.
Undantagsfilter är användbara för att fånga undantag som inträffar inom MVC-action, men de är inte lika flexibla som den inbyggda undantagshantermellanvara, UseExceptionHandler. Vi rekommenderar att du använder UseExceptionHandler, såvida du inte behöver utföra felhantering på olika sätt baserat på vilken MVC-åtgärd som väljs.
Modelltillståndsfel
Information om hur du hanterar modelltillståndsfel finns i Modellbindning och modellverifiering.
Probleminformation
Probleminformation är inte det enda svarsformatet som beskriver ett HTTP API-fel, men de används ofta för att rapportera fel för HTTP-API:er.
Tjänsten probleminformation implementerar IProblemDetailsService-gränssnittet, som har stöd för att skapa probleminformation i ASP.NET Core. 
              AddProblemDetails(IServiceCollection)-tilläggsmetoden på IServiceCollection registrerar standardimplementeringen IProblemDetailsService.
I ASP.NET Core-appar genererar följande mellanprogramvara HTTP-svar med probleminformation när AddProblemDetails anropas, förutom när HTTP-huvudet för Accept-begäran inte innehåller någon av de innehållstyper som stöds av den registrerade IProblemDetailsWriter (standard: application/json):
- ExceptionHandlerMiddleware: Genererar ett probleminformationssvar när en anpassad hanterare inte har definierats.
- StatusCodePagesMiddleware: Genererar ett probleminformationssvar som standard.
- 
              DeveloperExceptionPageMiddleware: Genererar ett probleminformationssvar under utveckling när HTTP-huvudet för Acceptbegäran inte innehållertext/html.
Följande kod konfigurerar appen för att generera ett probleminformationssvar för alla HTTP-klient- och serverfelsvar som inte har något brödtextinnehåll ännu:
builder.Services.AddProblemDetails();
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
I nästa avsnitt visas hur du anpassar svarstexten för probleminformation.
Anpassa probleminformation
Automatisk skapande av en ProblemDetails kan anpassas med något av följande alternativ:
- Använd ProblemDetailsOptions.CustomizeProblemDetails
- Använd en anpassad IProblemDetailsWriter
- Anropa IProblemDetailsServicei ett mellanprogram
              CustomizeProblemDetails åtgärd
Den genererade probleminformationen kan anpassas med hjälp av CustomizeProblemDetailsoch anpassningarna tillämpas på all probleminformation som genereras automatiskt.
Följande kod använder ProblemDetailsOptions för att ange CustomizeProblemDetails:
builder.Services.AddProblemDetails(options =>
    options.CustomizeProblemDetails = ctx =>
            ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName));
var app = builder.Build();        
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler();
    app.UseHsts();
}
app.UseStatusCodePages();
Ett HTTP Status 400 Bad Request slutpunktsresultat skapar till exempel följande svarstext för probleminformation:
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "Bad Request",
  "status": 400,
  "nodeId": "my-machine-name"
}
Anpassad IProblemDetailsWriter
En IProblemDetailsWriter implementering kan skapas för avancerade anpassningar.
public class SampleProblemDetailsWriter : IProblemDetailsWriter
{
    // Indicates that only responses with StatusCode == 400
    // are handled by this writer. All others are
    // handled by different registered writers if available.
    public bool CanWrite(ProblemDetailsContext context)
        => context.HttpContext.Response.StatusCode == 400;
    public ValueTask WriteAsync(ProblemDetailsContext context)
    {
        // Additional customizations.
        // Write to the response.
        var response = context.HttpContext.Response;
        return new ValueTask(response.WriteAsJsonAsync(context.ProblemDetails));
    }
}
              
              Obs! När du använder en anpassad IProblemDetailsWritermåste den anpassade IProblemDetailsWriter registreras innan du anropar AddRazorPages, AddControllers, AddControllersWithViewseller AddMvc:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IProblemDetailsWriter, SampleProblemDetailsWriter>();
var app = builder.Build();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsWriter>() is
            { } problemDetailsService)
        {
            if (problemDetailsService.CanWrite(new ProblemDetailsContext() { HttpContext = context }))
            {
                (string Detail, string Type) details = mathErrorFeature.MathError switch
                {
                    MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                        "https://en.wikipedia.org/wiki/Division_by_zero"),
                    _ => ("Negative or complex numbers are not valid input.",
                        "https://en.wikipedia.org/wiki/Square_root")
                };
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                    {
                        Title = "Bad Input",
                        Detail = details.Detail,
                        Type = details.Type
                    }
                });
            }
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.DivisionByZeroError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature
        {
            MathError = MathErrorType.NegativeRadicandError
        };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.Run();
Probleminformation från Middleware
Ett annat sätt att använda ProblemDetailsOptions med CustomizeProblemDetails är att ange ProblemDetails i mellanprogram. Ett probleminformationssvar kan skrivas genom att anropa IProblemDetailsService.WriteAsync:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
// Middleware to handle writing problem details to the response.
app.Use(async (context, next) =>
{
    await next(context);
    var mathErrorFeature = context.Features.Get<MathErrorFeature>();
    if (mathErrorFeature is not null)
    {
        if (context.RequestServices.GetService<IProblemDetailsService>() is
                                                           { } problemDetailsService)
        {
            (string Detail, string Type) details = mathErrorFeature.MathError switch
            {
                MathErrorType.DivisionByZeroError => ("Divison by zero is not defined.",
                "https://en.wikipedia.org/wiki/Division_by_zero"),
                _ => ("Negative or complex numbers are not valid input.", 
                "https://en.wikipedia.org/wiki/Square_root")
            };
            await problemDetailsService.WriteAsync(new ProblemDetailsContext
            {
                HttpContext = context,
                ProblemDetails =
                {
                    Title = "Bad Input",
                    Detail = details.Detail,
                    Type = details.Type
                }
            });
        }
    }
});
// /divide?numerator=2&denominator=4
app.MapGet("/divide", (HttpContext context, double numerator, double denominator) =>
{
    if (denominator == 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.DivisionByZeroError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(numerator / denominator);
});
// /squareroot?radicand=16
app.MapGet("/squareroot", (HttpContext context, double radicand) =>
{
    if (radicand < 0)
    {
        var errorType = new MathErrorFeature { MathError =
                                               MathErrorType.NegativeRadicandError };
        context.Features.Set(errorType);
        return Results.BadRequest();
    }
    return Results.Ok(Math.Sqrt(radicand));
});
app.MapControllers();
app.Run();
I föregående kod returnerar de minimala API-slutpunkterna /divide och /squareroot det förväntade anpassade problemsvaret vid felindata.
API-kontrollantens slutpunkter returnerar standardfelsvaret vid felindata, inte det anpassade problemsvaret. Standardproblemsvaret returneras eftersom API-kontrollanten har skrivit till svarsströmmen Probleminformation för felstatuskoderinnan IProblemDetailsService.WriteAsync anropas och svaret inte skrivs igen.
Följande ValuesController returnerar BadRequestResult, vilket skriver till svarsströmmen och därför förhindrar att ett anpassat problemsvar returneras.
[Route("api/[controller]/[action]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // /api/values/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return BadRequest();
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Följande Values3Controller returnerar ControllerBase.Problem så att det förväntade anpassade problemresultatet returneras:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values3Controller : ControllerBase
{
    // /api/values3/divide/1/2
    [HttpGet("{Numerator}/{Denominator}")]
    public IActionResult Divide(double Numerator, double Denominator)
    {
        if (Denominator == 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.DivisionByZeroError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Divison by zero is not defined.",
                type: "https://en.wikipedia.org/wiki/Division_by_zero",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Numerator / Denominator);
    }
    // /api/values3/squareroot/4
    [HttpGet("{radicand}")]
    public IActionResult Squareroot(double radicand)
    {
        if (radicand < 0)
        {
            var errorType = new MathErrorFeature
            {
                MathError = MathErrorType.NegativeRadicandError
            };
            HttpContext.Features.Set(errorType);
            return Problem(
                title: "Bad Input",
                detail: "Negative or complex numbers are not valid input.",
                type: "https://en.wikipedia.org/wiki/Square_root",
                statusCode: StatusCodes.Status400BadRequest
                );
        }
        return Ok(Math.Sqrt(radicand));
    }
}
Skapa en ProblemDetails-last för undantag
Tänk på följande app:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
app.MapControllers();
app.Run();
När ett undantag inträffar i icke-utvecklingsmiljöer är följande ett standardsvar ProblemDetails som returneras till klienten:
{
"type":"https://tools.ietf.org/html/rfc7231#section-6.6.1",
"title":"An error occurred while processing your request.",
"status":500,"traceId":"00-b644<snip>-00"
}
För de flesta appar är föregående kod allt som behövs för undantag. I följande avsnitt visas dock hur du får mer detaljerade problemsvar.
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet och skriva ett probleminformationssvar med IProblemDetailsService.WriteAsync:
using Microsoft.AspNetCore.Diagnostics;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler();
app.UseStatusCodePages();
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = Text.Plain;
            var title = "Bad Input";
            var detail = "Invalid input";
            var type = "https://errors.example.com/badInput";
            if (context.RequestServices.GetService<IProblemDetailsService>() is
                { } problemDetailsService)
            {
                var exceptionHandlerFeature =
               context.Features.Get<IExceptionHandlerFeature>();
                var exceptionType = exceptionHandlerFeature?.Error;
                if (exceptionType != null &&
                   exceptionType.Message.Contains("infinity"))
                {
                    title = "Argument exception";
                    detail = "Invalid input";
                    type = "https://errors.example.com/argumentException";
                }
                await problemDetailsService.WriteAsync(new ProblemDetailsContext
                {
                    HttpContext = context,
                    ProblemDetails =
                {
                    Title = title,
                    Detail = detail,
                    Type = type
                }
                });
            }
        });
    });
}
app.MapControllers();
app.Run();
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
En annan metod för att generera probleminformation är att använda NuGet-paketet från tredje part Hellang.Middleware.ProblemDetails som kan användas för att mappa undantag och klientfel till probleminformation.
Ytterligare resurser
Av Tom Dykstra
Den här artikeln beskriver vanliga metoder för att hantera fel i ASP.NET Core-webbappar. Se Hantera fel i ASP.NET Core API:er för webb-API:er.
Undantagssida för utvecklare
undantagssidan för utvecklare visar detaljerad information om ohanterade undantag för begäranden. ASP.NET Core-appar aktiverar utvecklarens undantagssida som standard när båda:
- Kör i utvecklingsmiljö .
- App som skapats med de aktuella mallarna, d.v.s. med hjälp av WebApplication.CreateBuilder.  Appar som skapats med hjälp av WebHost.CreateDefaultBuildermåste aktivera undantagssidan för utvecklare genom att anropaapp.UseDeveloperExceptionPageiConfigure.
Undantagssidan för utvecklare körs tidigt i middleware-pipelinen, så att den kan fånga ohanterade undantag som genereras i efterföljande mellanprogram.
Detaljerad undantagsinformation bör inte visas offentligt när appen körs i produktionsmiljön. Mer information om hur du konfigurerar miljöer finns i ASP.NET Core Runtime-miljöer.
Sidan Undantag för utvecklare kan innehålla följande information om undantaget och begäran:
- Stackspårning
- Frågesträngsparametrar, om några
- Cookies, om några
- Headers
Undantagssidan för utvecklare är inte garanterad att ange någon information. Använd logg för fullständig felinformation.
Undantagshanteringsida
Om du vill konfigurera en anpassad felhanteringssida för Produktionsmiljöanropar du UseExceptionHandler. Denna undantagshanterande mellanprogramvara:
- Fångar upp och loggar ohanterade undantag.
- Utför begäran på nytt i en alternativ pipeline med den angivna sökvägen. Begäran utförs inte igen om svaret redan har påbörjats. Den mallgenererade koden kör begäran igen med hjälp av sökvägen /Error.
Warning
Om den alternativa pipelinen genererar ett eget undantag, överväxlar Undantagshantering mellanprogram det ursprungliga undantaget.
I följande exempel lägger UseExceptionHandler till undantagshanteringsmellanprogram i miljöer som inte är utvecklingsmiljöer:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Appmallen Razor Pages innehåller en felsida (.cshtml) och PageModel -klass (ErrorModel) i mappen Pages. För en MVC-app innehåller projektmallen en Error-åtgärdsmetod och en felvy för den Home kontrollanten.
Undantagshanteringsmellanprogrammet kör begäran igen med hjälp av den ursprungliga HTTP-metoden. Om en slutpunkt för felhanterare är begränsad till en specifik uppsättning HTTP-metoder körs den endast för dessa HTTP-metoder. Till exempel körs en MVC-kontrollantåtgärd som använder attributet [HttpGet] endast för GET-begäranden. För att säkerställa att alla begäranden når sidan för anpassad felhantering ska du inte begränsa dem till en specifik uppsättning HTTP-metoder.
Så här hanterar du undantag på olika sätt baserat på den ursprungliga HTTP-metoden:
- Skapa flera hanteringsmetoder för Razor Pages. Använd till exempel OnGetför att hantera GET-undantag och användaOnPostför att hantera POST-undantag.
- För MVC använder du HTTP-verbattribut på flera åtgärder. Använd till exempel [HttpGet]för att hantera GET-undantag och använda[HttpPost]för att hantera POST-undantag.
Om du vill tillåta oautentiserade användare att visa sidan för anpassad felhantering kontrollerar du att den stöder anonym åtkomst.
Få åtkomst till undantaget
Använd IExceptionHandlerPathFeature för att komma åt undantaget och den ursprungliga sökvägen för begäran i en felhanterare. I följande exempel används IExceptionHandlerPathFeature för att få mer information om undantaget som utlöstes:
[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; }
    public void OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
        var exceptionHandlerPathFeature =
            HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
        {
            ExceptionMessage = "The file was not found.";
        }
        if (exceptionHandlerPathFeature?.Path == "/")
        {
            ExceptionMessage ??= string.Empty;
            ExceptionMessage += " Page: Home.";
        }
    }
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
Lambda för undantagshanterare
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet innan svaret returneras.
Följande kod använder en lambda för undantagshantering:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler(exceptionHandlerApp =>
    {
        exceptionHandlerApp.Run(async context =>
        {
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            // using static System.Net.Mime.MediaTypeNames;
            context.Response.ContentType = Text.Plain;
            await context.Response.WriteAsync("An exception was thrown.");
            var exceptionHandlerPathFeature =
                context.Features.Get<IExceptionHandlerPathFeature>();
            if (exceptionHandlerPathFeature?.Error is FileNotFoundException)
            {
                await context.Response.WriteAsync(" The file was not found.");
            }
            if (exceptionHandlerPathFeature?.Path == "/")
            {
                await context.Response.WriteAsync(" Page: Home.");
            }
        });
    });
    app.UseHsts();
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
UseStatusCodePages
Som standard tillhandahåller en ASP.NET Core-app inte någon statuskodsida för HTTP-felstatuskoder, till exempel 404 – Hittades inte. När appen anger en HTTP 400-599-felstatuskod som inte har någon brödtext returneras statuskoden och en tom svarstext. Om du vill aktivera standardhanterare med endast text för vanliga felstatuskoder anropar du UseStatusCodePages i Program.cs:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages();
Anropa UseStatusCodePages innan du begär hantering av mellanprogram. Anropa till exempel UseStatusCodePages före mellanskiktet för statiska filer och mellanskiktet för slutpunkter.
När UseStatusCodePages inte används returnerar navigering till en URL utan en slutpunkt ett webbläsarberoende felmeddelande som anger att slutpunkten inte kan hittas. När UseStatusCodePages anropas returnerar webbläsaren följande svar:
Status Code: 404; Not Found
              UseStatusCodePages används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
Note
Mellanprogrammet för statuskodsidor gör inte fånga undantag. Om du vill ange en anpassad felhanteringssida använder du sidan undantagshanterare.
Använd UseStatusCodePages med formatsträng
Om du vill anpassa svarsinnehållstypen och texten använder du överlagringen av UseStatusCodePages som tar en innehållstyp och formatsträng:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
// using static System.Net.Mime.MediaTypeNames;
app.UseStatusCodePages(Text.Plain, "Status Code Page: {0}");
I föregående kod är {0} en platshållare för felkoden.
              UseStatusCodePages med en formatsträng används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePages med lambda
Om du vill ange anpassad felhanterings- och svarsskrivningskod, använd en överlagring av UseStatusCodePages som tar ett lambda-uttryck:
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePages(async statusCodeContext =>
{
    // using static System.Net.Mime.MediaTypeNames;
    statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
    await statusCodeContext.HttpContext.Response.WriteAsync(
        $"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
              UseStatusCodePages med en lambda används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects utökningsmetod:
- Skickar en 302 – hittad statuskod till klienten.
- Omdirigerar klienten till slutpunkten för felhantering som anges i URL-mallen. Slutpunkten för felhantering visar vanligtvis felinformation och returnerar HTTP 200.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");
URL-mallen kan innehålla en {0} platshållare för statuskoden, enligt föregående kod. Om URL-mallen börjar med ~ (tilde) ersätts ~ av appens PathBase. När du anger en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen:
- Ska omdirigera klienten till en annan slutpunkt, vanligtvis i fall där en annan app bearbetar felet. För webbappar återspeglar klientens webbläsaradressfält den omdirigerade slutpunkten.
- Bör inte bevara och returnera den ursprungliga statuskoden med det första omdirigeringssvaret.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute utökningsmetod:
- Returnerar den ursprungliga statuskoden till klienten.
- Genererar svarstextens innehåll genom att köra begärandepipelinen igen med hjälp av en alternativ sökväg.
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/StatusCode/{0}");
Om en slutpunkt i appen har angetts skapar du en MVC-vy eller Razor sida för slutpunkten.
Den här metoden används ofta när appen ska:
- Bearbeta begäran utan att omdirigera till en annan slutpunkt. För webbappar återspeglar klientens webbläsaradressfält den ursprungligen begärda slutpunkten.
- Bevara och returnera den ursprungliga statuskoden med svaret.
URL-mallen måste börja med / och kan innehålla en platshållare {0} för statuskoden. Skicka statuskoden som en frågesträngsparameter genom att skicka ett andra argument till UseStatusCodePagesWithReExecute. Till exempel:
app.UseStatusCodePagesWithReExecute("/StatusCode", "?statusCode={0}");
Slutpunkten som bearbetar felet kan hämta den ursprungliga URL:en som genererade felet, enligt följande exempel:
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class StatusCodeModel : PageModel
{
    public int OriginalStatusCode { get; set; }
    public string? OriginalPathAndQuery { get; set; }
    public void OnGet(int statusCode)
    {
        OriginalStatusCode = statusCode;
        var statusCodeReExecuteFeature =
            HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
        if (statusCodeReExecuteFeature is not null)
        {
            OriginalPathAndQuery = string.Join(
                statusCodeReExecuteFeature.OriginalPathBase,
                statusCodeReExecuteFeature.OriginalPath,
                statusCodeReExecuteFeature.OriginalQueryString);
        }
    }
}
Inaktivera statuskodsidor
Om du vill inaktivera statuskodsidor för en MVC-kontrollant eller åtgärdsmetod använder du attributet [SkipStatusCodePages].
Om du vill inaktivera statuskodsidor för specifika begäranden i en Razor Pages-hanteringsmetod eller i en MVC-styrenhet använder du IStatusCodePagesFeature:
public void OnGet()
{
    var statusCodePagesFeature =
        HttpContext.Features.Get<IStatusCodePagesFeature>();
    if (statusCodePagesFeature is not null)
    {
        statusCodePagesFeature.Enabled = false;
    }
}
Kod för undantagshantering
Kod i undantagshanteringssidor kan också utlösa undantag. Sidor med produktionsfel bör testas noggrant och vara extra noggranna för att undvika egna undantag.
Svarsrubriker
När rubrikerna för ett svar har skickats:
- Appen kan inte ändra svarets statuskod.
- Undantagssidor eller hanterare kan inte köras. Svaret måste slutföras eller så avbryts anslutningen.
Hantering av serverfel
Förutom logiken för undantagshantering i en app kan HTTP-serverimplementering hantera vissa undantag. Om servern upptäcker ett undantag innan svarshuvuden skickas skickar servern ett 500 - Internal Server Error svar utan svarstext. Om servern får ett undantag efter att svarsrubriker har skickats, stänger servern anslutningen. Begäranden som inte hanteras av appen hanteras av servern. Alla undantag som inträffar när servern hanterar begäran hanteras av serverns undantagshantering. Appens anpassade felsidor, undantagshantering av mellanprogram och filter påverkar inte det här beteendet.
Undantagshantering vid start
Endast värdlagret kan hantera undantag som sker under appstarten. Värden kan konfigureras för att fånga startfel och fånga detaljerade fel.
Värdlagret kan visa en felsida för ett insamlat startfel endast om felet inträffar efter värdadress/portbindning. Om bindningen misslyckas:
- Värdlagret loggar ett kritiskt undantag.
- Dotnet-processen kraschar.
- Ingen felsida visas när HTTP-servern är Kestrel.
När du kör på IIS (eller Azure App Service) eller IIS Expressreturneras en 502.5 – Processfel av ASP.NET Core-modulen om processen inte kan starta. Mer information finns i Felsöka ASP.NET Core i Azure App Service och IIS.
Databasfelsida
Undantagsfiltret för databasutvecklare AddDatabaseDeveloperPageExceptionFilter samlar in databasrelaterade undantag som kan lösas med hjälp av Entity Framework Core-migreringar. När dessa undantag inträffar genereras ett HTML-svar med information om möjliga åtgärder för att lösa problemet. Den här sidan är endast aktiverad i utvecklingsmiljön. Följande kod lägger till undantagsfiltret för databasutvecklarens sida:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddRazorPages();
Undantagsfilter
I MVC-appar kan undantagsfilter konfigureras globalt eller per kontrollant eller per åtgärd. I Razor Pages-appar kan de konfigureras globalt eller per sidmodell. Dessa filter hanterar alla ohanterade undantag som inträffar under exekveringen av en controlleråtgärd eller ett annat filter. Mer information finns i filter i ASP.NET Core.
Undantagsfilter är användbara för att fånga undantag som inträffar inom MVC-action, men de är inte lika flexibla som den inbyggda undantagshantermellanvara, UseExceptionHandler. Vi rekommenderar att du använder UseExceptionHandler, såvida du inte behöver utföra felhantering på olika sätt baserat på vilken MVC-åtgärd som väljs.
Modelltillståndsfel
Information om hur du hanterar modelltillståndsfel finns i Modellbindning och modellverifiering.
Ytterligare resurser
Av Kirk Larkin, Tom Dykstraoch Steve Smith
Den här artikeln beskriver vanliga metoder för att hantera fel i ASP.NET Core-webbappar. Se Hantera fel i ASP.NET Core API:er för webb-API:er.
Visa eller ladda ned exempelkod. (Ladda ned.) Fliken Nätverk i utvecklarverktygen för F12-webbläsaren är användbar när du testar exempelappen.
Undantagssida för utvecklare
undantagssidan för utvecklare visar detaljerad information om ohanterade undantag för begäranden. Mallarna ASP.NET Core genererar följande kod:
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();
    });
}
Den föregående markerade koden aktiverar undantagssidan för utvecklare när appen körs i Utvecklingsmiljö.
Mallarna placerar UseDeveloperExceptionPage tidigt i pipelinen för mellanprogram så att de kan fånga ohanterade undantag som genereras i mellanprogram som följer.
Föregående kod aktiverar sidan Undantag för utvecklare endast när appen körs i utvecklingsmiljön. Detaljerad undantagsinformation bör inte visas offentligt när appen körs i produktionsmiljön. Mer information om hur du konfigurerar miljöer finns i ASP.NET Core Runtime-miljöer.
Sidan Undantag för utvecklare kan innehålla följande information om undantaget och begäran:
- Stackspårning
- Frågesträngsparametrar, om det finns några
- Eventuella cookies
- Headers
Undantagssidan för utvecklare är inte garanterad att ange någon information. Använd logg för fullständig felinformation.
Undantagshanteringsida
Om du vill konfigurera en anpassad felhanteringssida för Produktionsmiljöanropar du UseExceptionHandler. Denna undantagshanterande mellanprogramvara:
- Fångar upp och loggar ohanterade undantag.
- Utför begäran på nytt i en alternativ pipeline med den angivna sökvägen. Begäran utförs inte igen om svaret redan har påbörjats. Den mallgenererade koden kör begäran igen med hjälp av sökvägen /Error.
Warning
Om den alternativa pipelinen genererar ett eget undantag, överväxlar Undantagshantering mellanprogram det ursprungliga undantaget.
I följande exempel lägger UseExceptionHandler till undantagshanteringsmellanprogram i miljöer som inte är utvecklingsmiljöer:
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Appmallen Razor Pages innehåller en felsida (.cshtml) och PageModel -klass (ErrorModel) i mappen Pages. För en MVC-app innehåller projektmallen en Error-åtgärdsmetod och en felvy för den Home kontrollanten.
Undantagshanteringsmellanprogrammet kör begäran igen med hjälp av den ursprungliga HTTP-metoden. Om en slutpunkt för felhanterare är begränsad till en specifik uppsättning HTTP-metoder körs den endast för dessa HTTP-metoder. Till exempel körs en MVC-kontrollantåtgärd som använder attributet [HttpGet] endast för GET-begäranden. För att säkerställa att alla begäranden når sidan för anpassad felhantering ska du inte begränsa dem till en specifik uppsättning HTTP-metoder.
Så här hanterar du undantag på olika sätt baserat på den ursprungliga HTTP-metoden:
- Skapa flera hanteringsmetoder för Razor Pages. Använd till exempel OnGetför att hantera GET-undantag och användaOnPostför att hantera POST-undantag.
- För MVC använder du HTTP-verbattribut på flera åtgärder. Använd till exempel [HttpGet]för att hantera GET-undantag och använda[HttpPost]för att hantera POST-undantag.
Om du vill tillåta oautentiserade användare att visa sidan för anpassad felhantering kontrollerar du att den stöder anonym åtkomst.
Få åtkomst till undantaget
Använd IExceptionHandlerPathFeature för att komma åt undantaget och den ursprungliga sökvägen för begäran i en felhanterare. Följande kod lägger till ExceptionMessage till standard Pages/Error.cshtml.cs som genereras av ASP.NET Core-mallarna:
[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";
        }
    }
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
Testa undantaget i exempelappen:
- Ställ in miljön på produktionsläge.
- Ta bort kommentarerna från webBuilder.UseStartup<Startup>();iProgram.cs.
- Välj Utlös ett undantag på startsidan.
Lambda för undantagshanterare
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet innan svaret returneras.
Följande kod använder en lambda för undantagshantering:
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();
    });
}
Warning
Skicka inte känslig felinformation från IExceptionHandlerFeature eller IExceptionHandlerPathFeature till klienter. Att hantera fel är en säkerhetsrisk.
Testa undantagshanteringen av lambda i exempelappen:
- Ställ in miljön på produktionsläge.
- Ta bort kommentarerna från webBuilder.UseStartup<StartupLambda>();iProgram.cs.
- Välj Utlös ett undantag på startsidan.
UseStatusCodePages
Som standard tillhandahåller en ASP.NET Core-app inte någon statuskodsida för HTTP-felstatuskoder, till exempel 404 – Hittades inte. När appen anger en HTTP 400-599-felstatuskod som inte har någon brödtext returneras statuskoden och en tom svarstext. Om du vill ange statuskodsidor använder du mellanprogrammet för statuskodsidor. Om du vill aktivera standardhanterare med endast text för vanliga felstatuskoder anropar du UseStatusCodePages i metoden Startup.Configure:
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();
    });
}
Anropa UseStatusCodePages innan du begär hantering av mellanprogram. Anropa till exempel UseStatusCodePages före mellanskiktet för statiska filer och mellanskiktet för slutpunkter.
När UseStatusCodePages inte används returnerar navigering till en URL utan en slutpunkt ett webbläsarberoende felmeddelande som anger att slutpunkten inte kan hittas. Du kan till exempel navigera till Home/Privacy2. När UseStatusCodePages anropas returnerar webbläsaren:
Status Code: 404; Not Found
              UseStatusCodePages används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
För att testa UseStatusCodePages i exempelappen:
- Ställ in miljön på produktionsläge.
- Ta bort kommentarerna från webBuilder.UseStartup<StartupUseStatusCodePages>();iProgram.cs.
- Välj länkarna på startsidan på startsidan.
Note
Mellanprogrammet för statuskodsidor gör inte fånga undantag. Om du vill ange en anpassad felhanteringssida använder du sidan undantagshanterare.
Använd UseStatusCodePages med formatsträng
Om du vill anpassa svarsinnehållstypen och texten använder du överlagringen av UseStatusCodePages som tar en innehållstyp och formatsträng:
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();
    });
}
I föregående kod är {0} en platshållare för felkoden.
              UseStatusCodePages med en formatsträng används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
Om du vill testa UseStatusCodePages i exempelappentar du bort kommentarerna från webBuilder.UseStartup<StartupFormat>(); i Program.cs.
UseStatusCodePages med lambda
Om du vill ange anpassad felhanterings- och svarsskrivningskod, använd en överlagring av UseStatusCodePages som tar ett lambda-uttryck:
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 med en lambda används vanligtvis inte i produktion eftersom det returnerar ett meddelande som inte är användbart för användarna.
Om du vill testa UseStatusCodePages i exempelappentar du bort kommentarerna från webBuilder.UseStartup<StartupStatusLambda>(); i Program.cs.
UseStatusCodePagesWithRedirects
UseStatusCodePagesWithRedirects utökningsmetod:
- Skickar en 302 – hittad statuskod till klienten.
- Omdirigerar klienten till slutpunkten för felhantering som anges i URL-mallen. Slutpunkten för felhantering visar vanligtvis felinformation och returnerar HTTP 200.
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();
    });
}
URL-mallen kan innehålla en {0} platshållare för statuskoden, enligt föregående kod. Om URL-mallen börjar med ~ (tilde) ersätts ~ av appens PathBase. När du anger en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten. Ett Razor pages-exempel finns i Pages/MyStatusCode.cshtml i exempelappen .
Den här metoden används ofta när appen:
- Ska omdirigera klienten till en annan slutpunkt, vanligtvis i fall där en annan app bearbetar felet. För webbappar återspeglar klientens webbläsaradressfält den omdirigerade slutpunkten.
- Bör inte bevara och returnera den ursprungliga statuskoden med det första omdirigeringssvaret.
Om du vill testa UseStatusCodePages i exempelappentar du bort kommentarerna från webBuilder.UseStartup<StartupSCredirect>(); i Program.cs.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute utökningsmetod:
- Returnerar den ursprungliga statuskoden till klienten.
- Genererar svarstextens innehåll genom att köra begärandepipelinen igen med hjälp av en alternativ sökväg.
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();
    });
}
Om en slutpunkt i appen har angetts skapar du en MVC-vy eller Razor sida för slutpunkten. Kontrollera att UseStatusCodePagesWithReExecute placeras före UseRouting så att begäran kan omdirigeras till statussidan. Ett Razor pages-exempel finns i Pages/MyStatusCode2.cshtml i exempelappen .
Den här metoden används ofta när appen ska:
- Bearbeta begäran utan att omdirigera till en annan slutpunkt. För webbappar återspeglar klientens webbläsaradressfält den ursprungligen begärda slutpunkten.
- Bevara och returnera den ursprungliga statuskoden med svaret.
URL- och frågesträngsmallar kan innehålla en platshållare {0} för statuskod. URL-mallen måste börja med /.
Slutpunkten som bearbetar felet kan hämta den ursprungliga URL:en som genererade felet, enligt följande exempel:
[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;
        }
    }
}
Ett Razor pages-exempel finns i Pages/MyStatusCode2.cshtml i exempelappen .
Om du vill testa UseStatusCodePages i exempelappentar du bort kommentarerna från webBuilder.UseStartup<StartupSCreX>(); i Program.cs.
Inaktivera statuskodsidor
Om du vill inaktivera statuskodsidor för en MVC-kontrollant eller åtgärdsmetod använder du attributet [SkipStatusCodePages].
Om du vill inaktivera statuskodsidor för specifika begäranden i en Razor Pages-hanteringsmetod eller i en MVC-styrenhet använder du IStatusCodePagesFeature:
public void OnGet()
{
    // using Microsoft.AspNetCore.Diagnostics;
    var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();
    if (statusCodePagesFeature != null)
    {
        statusCodePagesFeature.Enabled = false;
    }
}
Kod för undantagshantering
Kod i undantagshanteringssidor kan också utlösa undantag. Sidor med produktionsfel bör testas noggrant och vara extra noggranna för att undvika egna undantag.
Svarsrubriker
När rubrikerna för ett svar har skickats:
- Appen kan inte ändra svarets statuskod.
- Undantagssidor eller hanterare kan inte köras. Svaret måste slutföras eller så avbryts anslutningen.
Hantering av serverfel
Förutom logiken för undantagshantering i en app kan HTTP-serverimplementering hantera vissa undantag. Om servern upptäcker ett undantag innan svarshuvuden skickas skickar servern ett 500 - Internal Server Error svar utan svarstext. Om servern får ett undantag efter att svarsrubriker har skickats, stänger servern anslutningen. Begäranden som inte hanteras av appen hanteras av servern. Alla undantag som inträffar när servern hanterar begäran hanteras av serverns undantagshantering. Appens anpassade felsidor, undantagshantering av mellanprogram och filter påverkar inte det här beteendet.
Undantagshantering vid start
Endast värdlagret kan hantera undantag som sker under appstarten. Värden kan konfigureras för att fånga startfel och fånga detaljerade fel.
Värdlagret kan visa en felsida för ett insamlat startfel endast om felet inträffar efter värdadress/portbindning. Om bindningen misslyckas:
- Värdlagret loggar ett kritiskt undantag.
- Dotnet-processen kraschar.
- Ingen felsida visas när HTTP-servern är Kestrel.
När du kör på IIS (eller Azure App Service) eller IIS Expressreturneras en 502.5 – Processfel av ASP.NET Core-modulen om processen inte kan starta. Mer information finns i Felsöka ASP.NET Core i Azure App Service och IIS.
Databasfelsida
Undantagsfiltret för databasutvecklare AddDatabaseDeveloperPageExceptionFilter samlar in databasrelaterade undantag som kan lösas med hjälp av Entity Framework Core-migreringar. När dessa undantag inträffar genereras ett HTML-svar med information om möjliga åtgärder för att lösa problemet. Den här sidan är endast aktiverad i utvecklingsmiljön. Följande kod genererades av mallarna ASP.NET Core Razor Pages när enskilda användarkonton angavs:
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();
}
Undantagsfilter
I MVC-appar kan undantagsfilter konfigureras globalt eller per kontrollant eller per åtgärd. I Razor Pages-appar kan de konfigureras globalt eller per sidmodell. Dessa filter hanterar alla ohanterade undantag som inträffar under exekveringen av en controlleråtgärd eller ett annat filter. Mer information finns i filter i ASP.NET Core.
Undantagsfilter är användbara för att fånga undantag som inträffar inom MVC-action, men de är inte lika flexibla som den inbyggda undantagshantermellanvara, UseExceptionHandler. Vi rekommenderar att du använder UseExceptionHandler, såvida du inte behöver utföra felhantering på olika sätt baserat på vilken MVC-åtgärd som väljs.
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();
    });
}
Modelltillståndsfel
Information om hur du hanterar modelltillståndsfel finns i Modellbindning och modellverifiering.
Ytterligare resurser
Av Tom Dykstraoch Steve Smith
Den här artikeln beskriver vanliga metoder för att hantera fel i ASP.NET Core-webbappar. Se Hantera fel i ASP.NET Core API:er för webb-API:er.
Visa eller ladda ned exempelkod. (Så här laddar du ner.)
Undantagssida för utvecklare
Undantag för Utvecklare-sidan visar detaljerad information om förfrågningsundantag. Mallarna ASP.NET Core genererar följande kod:
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Föregående kod aktiverar undantagssidan för utvecklare när appen körs i Utvecklingsmiljö.
Mallarna placerar UseDeveloperExceptionPage före något mellanlager, så undantag fångas i det efterföljande mellanlagret.
Föregående kod aktiverar sidan Undantag för utvecklare endast när appen körs i utvecklingsmiljön. Detaljerad undantagsinformation bör inte visas offentligt när appen körs i produktion. Mer information om hur du konfigurerar miljöer finns i ASP.NET Core Runtime-miljöer.
Sidan Undantag för utvecklare innehåller följande information om undantaget och begäran:
- Stackspårning
- Frågesträngsparametrar, om det finns några
- Eventuella cookies
- Headers
Undantagshanteringsida
Om du vill konfigurera en anpassad sida för felhantering för produktionsmiljön använder du mellanprogrammet Undantagshantering. Mellanprogrammet:
- Fångar upp och loggar undantag.
- Kör begäran på nytt i en alternativ pipeline för den angivna sidan eller kontrollanten. Begäran utförs inte igen om svaret redan har påbörjats. Den mallgenererade koden kör om begäran till /Error.
I följande exempel lägger UseExceptionHandler till undantagshanteringsmellanprogram i miljöer som inte är utvecklingsmiljöer:
if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}
Appmallen Razor Pages innehåller en felsida (.cshtml) och PageModel -klass (ErrorModel) i mappen Pages. För en MVC-app innehåller projektmallen en metod för felåtgärd och en felvy i Home kontrollanten.
Markera inte felhanteraråtgärdsmetoden med HTTP-metodattribut, till exempel HttpGet. Explicita verb förhindrar att vissa begäranden når metoden. Tillåt anonym åtkomst till metoden om oautentiserade användare ska se felvyn.
Få åtkomst till undantaget
Använd IExceptionHandlerPathFeature för att komma åt undantaget och den ursprungliga sökvägen för begäran på en felhanterarkontrollant eller sida:
[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";
        }
    }
}
Warning
Tillhandahåll inte känslig felinformation till klienterna. Att hantera fel är en säkerhetsrisk.
Om du vill utlösa föregående sida för undantagshantering anger du miljön till produktionsmiljö och framtvingar ett undantag.
Lambda för undantagshanterare
Ett alternativ till en anpassad undantagshanterarsida är att ange en lambda för UseExceptionHandler. Med hjälp av en lambda kan du komma åt felet innan svaret returneras.
Här är ett exempel på hur du använder en lambda för undantagshantering:
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();
}
I föregående kod läggs await context.Response.WriteAsync(new string(' ', 512)); till så att Webbläsaren Internet Explorer visar felmeddelandet i stället för ett IE-felmeddelande. Mer information finns i det här GitHub-ärendet.
Warning
Skicka inte känslig felinformation från IExceptionHandlerFeature eller IExceptionHandlerPathFeature till klienter. Att hantera fel är en säkerhetsrisk.
Om du vill se resultatet av undantagshanteringen av lambda i exempelappen använder du direktiven ProdEnvironment och ErrorHandlerLambda förprocessorn och väljer Utlös ett undantag på startsidan.
UseStatusCodePages
Som standard tillhandahåller inte en ASP.NET Core-app någon statuskodsida för HTTP-statuskoder, till exempel 404 – Hittades inte. Appen returnerar en statuskod och en tom svarstext. Om du vill ange statuskodsidor använder du mellanprogram för statuskodsidor.
Mellanprogrammet görs tillgängligt av paketet Microsoft.AspNetCore.Diagnostics.
Om du vill aktivera standardhanterare med endast text för vanliga felstatuskoder anropar du UseStatusCodePages i metoden Startup.Configure:
app.UseStatusCodePages();
Anropa UseStatusCodePages innan du begär hantering av mellanprogram (till exempel Static File Middleware och MVC Middleware).
När UseStatusCodePages inte används returnerar navigering till en URL utan en slutpunkt ett webbläsarberoende felmeddelande som anger att slutpunkten inte kan hittas. Du kan till exempel navigera till Home/Privacy2. När UseStatusCodePages anropas returnerar webbläsaren:
Status Code: 404; Not Found
Använd UseStatusCodePages med formatsträng
Om du vill anpassa svarsinnehållstypen och texten använder du överlagringen av UseStatusCodePages som tar en innehållstyp och formatsträng:
app.UseStatusCodePages(
    "text/plain", "Status code page, status code: {0}");
UseStatusCodePages med lambda
Om du vill ange anpassad felhanterings- och svarsskrivningskod, använd en överlagring av UseStatusCodePages som tar ett lambda-uttryck:
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
UseStatusCodePagesWithRedirects utökningsmetod:
- Skickar en 302 – hittad statuskod till klienten.
- Omdirigerar klienten till den plats som anges i URL-mallen.
app.UseStatusCodePagesWithRedirects("/StatusCode?code={0}");
URL-mallen kan innehålla en {0}-platshållare för statuskoden, som visas i exemplet. Om URL-mallen börjar med ~ (tilde) ersätts ~ av appens PathBase. Om du pekar på en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten. Ett 
Den här metoden används ofta när appen:
- Ska omdirigera klienten till en annan slutpunkt, vanligtvis i fall där en annan app bearbetar felet. För webbappar återspeglar klientens webbläsaradressfält den omdirigerade slutpunkten.
- Bör inte bevara och returnera den ursprungliga statuskoden med det första omdirigeringssvaret.
UseStatusCodePagesWithReExecute
UseStatusCodePagesWithReExecute utökningsmetod:
- Returnerar den ursprungliga statuskoden till klienten.
- Genererar svarstextens innehåll genom att köra begärandepipelinen igen med hjälp av en alternativ sökväg.
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");
Om du pekar på en slutpunkt i appen skapar du en MVC-vy eller Razor sida för slutpunkten. Kontrollera att UseStatusCodePagesWithReExecute placeras före UseRouting så att begäran kan omdirigeras till statussidan. Ett 
Den här metoden används ofta när appen ska:
- Bearbeta begäran utan att omdirigera till en annan slutpunkt. För webbappar återspeglar klientens webbläsaradressfält den ursprungligen begärda slutpunkten.
- Bevara och returnera den ursprungliga statuskoden med svaret.
Url- och frågesträngmallarna kan innehålla en platshållare ({0}) för statuskoden. URL-mallen måste börja med ett snedstreck (/). När du använder en platshållare i sökvägen kontrollerar du att slutpunkten (sidan eller kontrollanten) kan bearbeta sökvägssegmentet. Till exempel bör en Razor sida för fel acceptera det valfria sökvägssegmentvärdet med @page-direktivet:
@page "{code?}"
Slutpunkten som bearbetar felet kan hämta den ursprungliga URL:en som genererade felet, enligt följande exempel:
var statusCodeReExecuteFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
if (statusCodeReExecuteFeature != null)
{
    OriginalURL =
        statusCodeReExecuteFeature.OriginalPathBase
        + statusCodeReExecuteFeature.OriginalPath
        + statusCodeReExecuteFeature.OriginalQueryString;
}
Markera inte felhanteraråtgärdsmetoden med HTTP-metodattribut, till exempel HttpGet. Explicita verb förhindrar att vissa begäranden når metoden. Tillåt anonym åtkomst till metoden om oautentiserade användare ska se felvyn.
Inaktivera statuskodsidor
Om du vill inaktivera statuskodsidor för en MVC-kontrollant eller åtgärdsmetod använder du attributet [SkipStatusCodePages].
Om du vill inaktivera statuskodsidor för specifika begäranden i en Razor Pages-hanteringsmetod eller i en MVC-styrenhet använder du IStatusCodePagesFeature:
var statusCodePagesFeature = HttpContext.Features.Get<IStatusCodePagesFeature>();
if (statusCodePagesFeature != null)
{
    statusCodePagesFeature.Enabled = false;
}
Kod för undantagshantering
Kod i undantagshanteringssidor kan utlösa undantag. Det är ofta en bra idé att produktionsfelsidor består av rent statiskt innehåll.
Svarsrubriker
När rubrikerna för ett svar har skickats:
- Appen kan inte ändra svarets statuskod.
- Undantagssidor eller hanterare kan inte köras. Svaret måste slutföras eller så avbryts anslutningen.
Hantering av serverfel
Förutom logiken för undantagshantering i din app kan HTTP-serverimplementering hantera vissa undantag. Om servern upptäcker ett undantag innan svarshuvuden skickas skickar servern ett 500 – internt serverfel svar utan svarstext. Om servern får ett undantag efter att svarsrubriker har skickats, stänger servern anslutningen. Begäranden som inte hanteras av din app hanteras av servern. Alla undantag som inträffar när servern hanterar begäran hanteras av serverns undantagshantering. Appens anpassade felsidor, undantagshantering av mellanprogram och filter påverkar inte det här beteendet.
Undantagshantering vid start
Endast värdlagret kan hantera undantag som sker under appstarten. Värden kan konfigureras för att fånga startfel och fånga detaljerade fel.
Värdlagret kan visa en felsida för ett insamlat startfel endast om felet inträffar efter värdadress/portbindning. Om bindningen misslyckas:
- Värdlagret loggar ett kritiskt undantag.
- Dotnet-processen kraschar.
- Ingen felsida visas när HTTP-servern är Kestrel.
När du kör på IIS (eller Azure App Service) eller IIS Expressreturneras en 502.5 – Processfel av ASP.NET Core-modulen om processen inte kan starta. Mer information finns i Felsöka ASP.NET Core i Azure App Service och IIS.
Databasfelsida
Database Error Page Middleware samlar in databasrelaterade undantag som kan lösas med hjälp av Entity Framework-migreringar. När dessa undantag inträffar genereras ett HTML-svar med information om möjliga åtgärder för att lösa problemet. Den här sidan bör endast aktiveras i utvecklingsmiljön. Aktivera sidan genom att lägga till kod i Startup.Configure:
if (env.IsDevelopment())
{
    app.UseDatabaseErrorPage();
}
UseDatabaseErrorPage kräver Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore NuGet-paketet.
Undantagsfilter
I MVC-appar kan undantagsfilter konfigureras globalt eller per kontrollant eller per åtgärd. I Razor Pages-appar kan de konfigureras globalt eller per sidmodell. Dessa filter hanterar alla ohanterade undantag som inträffar under körningen av en kontrollantåtgärd eller ett annat filter. Mer information finns i filter i ASP.NET Core.
Tip
Undantagsfilter är användbara för att fånga undantag som inträffar inom MVC-funktioner, men de är inte lika flexibla som undantagshanteringsmellanlager. Vi rekommenderar att du använder mellanprogrammet. Använd endast filter där du behöver utföra felhantering på olika sätt baserat på vilken MVC-åtgärd som väljs.
Modelltillståndsfel
Information om hur du hanterar modelltillståndsfel finns i Modellbindning och modellverifiering.
Ytterligare resurser
ASP.NET Core