Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Note
Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikel voor de huidige release.
Warning
Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET- en .NET Core-ondersteuningsbeleid voor meer informatie. Zie de .NET 9-versie van dit artikel voor de huidige release.
Important
Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.
Zie de .NET 9-versie van dit artikel voor de huidige release.
In dit artikel wordt beschreven hoe u fouten kunt afhandelen en foutafhandeling kunt aanpassen in op controller gebaseerde ASP.NET Core-web-API's. Zie Fouten in ASP.NET Core verwerken en fouten verwerken in minimale API's voor informatie over foutafhandeling in minimale API's.
Uitzonderingspagina voor ontwikkelaars
Op de uitzonderingspagina voor ontwikkelaars wordt gedetailleerde informatie weergegeven over niet-verwerkte aanvraag-uitzonderingen. Het maakt gebruik DeveloperExceptionPageMiddleware van het vastleggen van synchrone en asynchrone uitzonderingen van de HTTP-pijplijn en voor het genereren van foutreacties. De ontwikkelaarsexceptiepagina draait vroeg in de middleware-pijplijn, zodat onopgevangen uitzonderingen die in de daaropvolgende middleware worden gegooid, kunnen worden opgevangen.
ASP.NET Core-apps de uitzonderingspagina voor ontwikkelaars standaard inschakelen wanneer beide:
- Wordt uitgevoerd in de ontwikkelomgeving.
- De app is gemaakt met de huidige sjablonen, dat wil gezegd met behulp van WebApplication.CreateBuilder.
Apps die zijn gemaakt met behulp van eerdere sjablonen, dat wil zeggen door WebHost.CreateDefaultBuilder te gebruiken, kunnen de uitzonderingspagina voor ontwikkelaars inschakelen door app.UseDeveloperExceptionPage
aan te roepen.
Warning
Schakel de uitzonderingspagina voor ontwikkelaars alleen in als de app wordt uitgevoerd in de ontwikkelomgeving. Deel geen gedetailleerde uitzonderingsgegevens openbaar wanneer de app in productie wordt uitgevoerd. Zie Meerdere omgevingen gebruiken in ASP.NET Core voor meer informatie over het configureren van omgevingen.
De uitzonderingspagina voor ontwikkelaars kan de volgende informatie bevatten over de uitzondering en de aanvraag:
- Stack trace
- Queryreeksparameters, indien van toepassing
- Cookies, indien van toepassing
- Headers
- Eindpuntmetagegevens, indien van toepassing
De uitzonderingspagina voor ontwikkelaars is niet gegarandeerd informatie te verstrekken. Gebruik Logging voor volledige foutinformatie.
In de volgende afbeelding ziet u een voorbeeld van een uitzonderingspagina voor ontwikkelaars met animatie om de tabbladen en de weergegeven informatie weer te geven:
Als reactie op een aanvraag met een Accept: text/plain
header retourneert de uitzonderingspagina voor ontwikkelaars tekst zonder opmaak in plaats van HTML. For example:
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
Ga als volgende te werk om de uitzonderingspagina voor ontwikkelaars weer te geven:
Voeg de volgende controlleractie toe aan een api op basis van een controller. De actie genereert een uitzondering wanneer het eindpunt wordt aangevraagd.
[HttpGet("Throw")] public IActionResult Throw() => throw new Exception("Sample exception.");
Voer de app uit in de ontwikkelomgeving.
Ga naar het eindpunt dat is gedefinieerd door de controlleractie.
Exception handler
In niet-ontwikkelomgevingen gebruikt u Middleware voor uitzonderingsafhandeling om een foutpayload te produceren:
UseExceptionHandler Roep
Program.cs
in aan om de Middleware voor uitzonderingsafhandeling toe te voegen:var app = builder.Build(); app.UseHttpsRedirection(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/error"); } app.UseAuthorization(); app.MapControllers(); app.Run();
Configureer een controlleractie om te reageren op de
/error
route:[Route("/error")] public IActionResult HandleError() => Problem();
Met de voorgaande HandleError
actie wordt een rfC 7807-compatibele nettolading naar de client verzonden.
Warning
Markeer de actiemethode voor de fouthandler niet met HTTP-methodekenmerken, zoals HttpGet
. Expliciete werkwoorden voorkomen dat sommige aanvragen de actiemethode bereiken.
Voor web-API's die gebruikmaken van Swagger/OpenAPI, markeert u de actie fouthandler met het kenmerk [ApiExplorerSettings] en stelt u de eigenschap in IgnoreApi op true
. Deze kenmerkconfiguratie sluit de actie fouthandler uit van de OpenAPI-specificatie van de app:
[ApiExplorerSettings(IgnoreApi = true)]
Anonieme toegang tot de methode toestaan als niet-geverifieerde gebruikers de fout moeten zien.
Middleware voor uitzonderingsafhandeling kan ook worden gebruikt in de ontwikkelomgeving om een consistente payload-indeling te produceren in alle omgevingen:
Program.cs
Registreer omgevingsspecifieke Middleware-exemplaren voor uitzonderingsafhandeling:if (app.Environment.IsDevelopment()) { app.UseExceptionHandler("/error-development"); } else { app.UseExceptionHandler("/error"); }
In de voorgaande code wordt de middleware geregistreerd bij:
- Een route van
/error-development
in de ontwikkelomgeving. - Een route van
/error
niet-ontwikkelomgevingen.
- Een route van
Controlleracties toevoegen voor zowel de ontwikkelings- als niet-ontwikkelingsroutes:
[Route("/error-development")] public IActionResult HandleErrorDevelopment( [FromServices] IHostEnvironment hostEnvironment) { if (!hostEnvironment.IsDevelopment()) { return NotFound(); } var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>()!; return Problem( detail: exceptionHandlerFeature.Error.StackTrace, title: exceptionHandlerFeature.Error.Message); } [Route("/error")] public IActionResult HandleError() => Problem();
Uitzonderingen gebruiken om het antwoord te wijzigen
De inhoud van het antwoord kan worden gewijzigd van buiten de controller met behulp van een aangepaste uitzondering en een actiefilter:
Maak een bekend uitzonderingstype met de naam
HttpResponseException
:public class HttpResponseException : Exception { public HttpResponseException(int statusCode, object? value = null) => (StatusCode, Value) = (statusCode, value); public int StatusCode { get; } public object? Value { get; } }
Maak een actiefilter met de naam
HttpResponseExceptionFilter
:public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter { public int Order => int.MaxValue - 10; public void OnActionExecuting(ActionExecutingContext context) { } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception is HttpResponseException httpResponseException) { context.Result = new ObjectResult(httpResponseException.Value) { StatusCode = httpResponseException.StatusCode }; context.ExceptionHandled = true; } } }
Het voorgaande filter geeft een
Order
van de maximumwaarde voor gehele getallen min 10 op. HierdoorOrder
kunnen andere filters aan het einde van de pijplijn worden uitgevoerd.Voeg
Program.cs
in het actiefilter het volgende toe aan de verzameling filters:builder.Services.AddControllers(options => { options.Filters.Add<HttpResponseExceptionFilter>(); });
Foutreactie bij validatiefout
Voor web-API-controllers reageert MVC met een ValidationProblemDetails antwoordtype wanneer modelvalidatie mislukt. MVC gebruikt de resultaten van het samenstellen van InvalidModelStateResponseFactory de foutreactie voor een validatiefout. In het volgende voorbeeld wordt de standaardfactory vervangen door een implementatie die ook ondersteuning biedt voor het opmaken van antwoorden als XML, in Program.cs
:
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
new BadRequestObjectResult(context.ModelState)
{
ContentTypes =
{
// using static System.Net.Mime.MediaTypeNames;
Application.Json,
Application.Xml
}
};
})
.AddXmlSerializerFormatters();
Antwoord van clientfout
Er wordt een foutresultaat gedefinieerd als resultaat met een HTTP-statuscode van 400 of hoger. Voor web-API-controllers transformeert MVC een foutresultaat om een ProblemDetails.
Het automatisch maken van een ProblemDetails
voor foutcodes is standaard ingeschakeld, maar foutreacties kunnen op een van de volgende manieren worden geconfigureerd:
- De service voor probleemdetails gebruiken
- Implement ProblemDetailsFactory
- Use ApiBehaviorOptions.ClientErrorMapping
Antwoord met standaardprobleemdetails
Het volgende Program.cs
bestand is gegenereerd door de webtoepassingssjablonen voor API-controllers:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Houd rekening met de volgende controller, die wordt geretourneerd BadRequest wanneer de invoer ongeldig is:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values2Controller : ControllerBase
{
// /api/values2/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
return BadRequest();
}
return Ok(Numerator / Denominator);
}
// /api/values2 /squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
return BadRequest();
}
return Ok(Math.Sqrt(radicand));
}
}
Er wordt een antwoord voor probleemdetails gegenereerd met de voorgaande code wanneer een van de volgende voorwaarden van toepassing is:
- Het
/api/values2/divide
eindpunt wordt aangeroepen met een nul noemer. - Het
/api/values2/squareroot
eindpunt wordt aangeroepen met een radicand kleiner dan nul.
De standaardtekst van de antwoordtekst met probleemdetails heeft de volgende type
, title
en status
waarden:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Bad Request",
"status": 400,
"traceId": "00-84c1fd4063c38d9f3900d06e56542d48-85d1d4-00"
}
Service voor probleemdetails
ASP.NET Core biedt ondersteuning voor het maken van probleemdetails voor HTTP-API's met behulp van de IProblemDetailsService. Zie de service Probleemdetails voor meer informatie.
Met de volgende code wordt de app geconfigureerd voor het genereren van een antwoord op probleemdetails voor alle HTTP-client- en serverfoutreacties die nog geen hoofdtekstinhoud hebben:
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();
Houd rekening met de API-controller uit de vorige sectie, die retourneert BadRequest wanneer de invoer ongeldig is:
[Route("api/[controller]/[action]")]
[ApiController]
public class Values2Controller : ControllerBase
{
// /api/values2/divide/1/2
[HttpGet("{Numerator}/{Denominator}")]
public IActionResult Divide(double Numerator, double Denominator)
{
if (Denominator == 0)
{
return BadRequest();
}
return Ok(Numerator / Denominator);
}
// /api/values2 /squareroot/4
[HttpGet("{radicand}")]
public IActionResult Squareroot(double radicand)
{
if (radicand < 0)
{
return BadRequest();
}
return Ok(Math.Sqrt(radicand));
}
}
Er wordt een antwoord voor probleemdetails gegenereerd met de voorgaande code wanneer een van de volgende voorwaarden van toepassing is:
- Er wordt een ongeldige invoer opgegeven.
- De URI heeft geen overeenkomend eindpunt.
- Er treedt een onverwerkte uitzondering op.
Het automatisch maken van een ProblemDetails
voor foutcodes is uitgeschakeld wanneer de SuppressMapClientErrors eigenschap is ingesteld true
op:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressMapClientErrors = true;
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Wanneer een API-controller wordt geretourneerd BadRequest
, wordt met behulp van de voorgaande code een HTTP 400-antwoordstatus geretourneerd zonder hoofdtekst van het antwoord.
SuppressMapClientErrors
voorkomt dat er een ProblemDetails
antwoord wordt gemaakt, zelfs wanneer een API Controller-eindpunt wordt aangeroepen WriteAsync
.
WriteAsync
wordt verderop in dit artikel uitgelegd.
In de volgende sectie ziet u hoe u de hoofdtekst van de antwoordtekst van de probleemdetails kunt aanpassen, om CustomizeProblemDetailseen nuttiger antwoord te retourneren. Zie Details van het probleem aanpassen voor meer aanpassingsopties.
Probleemdetails aanpassen met CustomizeProblemDetails
De volgende code gebruikt ProblemDetailsOptions om in te stellen CustomizeProblemDetails:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddProblemDetails(options =>
options.CustomizeProblemDetails = (context) =>
{
var mathErrorFeature = context.HttpContext.Features
.Get<MathErrorFeature>();
if (mathErrorFeature is not null)
{
(string Detail, string Type) details = mathErrorFeature.MathError switch
{
MathErrorType.DivisionByZeroError =>
("Divison by zero is not defined.",
"https://wikipedia.org/wiki/Division_by_zero"),
_ => ("Negative or complex numbers are not valid input.",
"https://wikipedia.org/wiki/Square_root")
};
context.ProblemDetails.Type = details.Type;
context.ProblemDetails.Title = "Bad Input";
context.ProblemDetails.Detail = details.Detail;
}
}
);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStatusCodePages();
app.UseAuthorization();
app.MapControllers();
app.Run();
De bijgewerkte API-controller:
[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));
}
}
De volgende code bevat de MathErrorFeature
en MathErrorType
, die worden gebruikt met het voorgaande voorbeeld:
// Custom Http Request Feature
class MathErrorFeature
{
public MathErrorType MathError { get; set; }
}
// Custom math errors
enum MathErrorType
{
DivisionByZeroError,
NegativeRadicandError
}
Er wordt een antwoord voor probleemdetails gegenereerd met de voorgaande code wanneer een van de volgende voorwaarden van toepassing is:
- Het
/divide
eindpunt wordt aangeroepen met een nul noemer. - Het
/squareroot
eindpunt wordt aangeroepen met een radicand kleiner dan nul. - De URI heeft geen overeenkomend eindpunt.
De antwoordtekst van de probleemdetails bevat het volgende wanneer een squareroot
van beide eindpunten wordt aangeroepen met een radicand kleiner dan nul:
{
"type": "https://en.wikipedia.org/wiki/Square_root",
"title": "Bad Input",
"status": 400,
"detail": "Negative or complex numbers are not allowed."
}
Voorbeeldcode weergeven of downloaden
ProblemDetailsFactory
implementeren
MVC gebruikt Microsoft.AspNetCore.Mvc.Infrastructure.ProblemDetailsFactory om alle exemplaren van ProblemDetails en ValidationProblemDetails. Deze fabriek wordt gebruikt voor:
- Clientfoutreacties
- Foutreacties bij validatiefouten
- ControllerBase.Problem en ControllerBase.ValidationProblem
Registreer een aangepaste implementatie van ProblemDetailsFactory :Program.cs
builder.Services.AddControllers();
builder.Services.AddTransient<ProblemDetailsFactory, SampleProblemDetailsFactory>();
Gebruik ApiBehaviorOptions.ClientErrorMapping
Gebruik de ClientErrorMapping eigenschap om de inhoud van het ProblemDetails
antwoord te configureren. Met de volgende code wordt Program.cs
bijvoorbeeld de Link eigenschap bijgewerkt voor 404-antwoorden:
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
Additional resources
In dit artikel wordt beschreven hoe u fouten kunt afhandelen en foutafhandeling kunt aanpassen met ASP.NET Core-web-API's.
Uitzonderingspagina voor ontwikkelaars
Op de uitzonderingspagina voor ontwikkelaars worden gedetailleerde stacktraceringen weergegeven voor serverfouten. Het maakt gebruik DeveloperExceptionPageMiddleware van het vastleggen van synchrone en asynchrone uitzonderingen van de HTTP-pijplijn en voor het genereren van foutreacties. Denk bijvoorbeeld aan de volgende controlleractie, waarmee een uitzondering wordt gegenereerd:
[HttpGet("Throw")]
public IActionResult Throw() =>
throw new Exception("Sample exception.");
Wanneer de uitzonderingspagina voor ontwikkelaars een niet-verwerkte uitzondering detecteert, wordt er een standaardantwoord zonder opmaak gegenereerd dat vergelijkbaar is met het volgende voorbeeld:
HTTP/1.1 500 Internal Server Error
Content-Type: text/plain; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
System.Exception: Sample exception.
at HandleErrorsSample.Controllers.ErrorsController.Get() in ...
at lambda_method1(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
...
Als de client een HTML-indeling aanvraagt, genereert de uitzonderingspagina voor ontwikkelaars een antwoord dat vergelijkbaar is met het volgende voorbeeld:
HTTP/1.1 500 Internal Server Error
Content-Type: text/html; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Internal Server Error</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
font-size: .813em;
color: #222;
background-color: #fff;
}
h1 {
color: #44525e;
margin: 15px 0 15px 0;
}
...
Als u een HTML-opgemaakt antwoord wilt aanvragen, stelt u de Accept
HTTP-aanvraagheader in op text/html
.
Warning
Schakel de uitzonderingspagina voor ontwikkelaars alleen in als de app wordt uitgevoerd in de ontwikkelomgeving. Deel geen gedetailleerde uitzonderingsgegevens openbaar wanneer de app in productie wordt uitgevoerd. Zie Meerdere omgevingen gebruiken in ASP.NET Core voor meer informatie over het configureren van omgevingen.
Exception handler
In niet-ontwikkelomgevingen gebruikt u Middleware voor uitzonderingsafhandeling om een foutpayload te produceren:
UseExceptionHandler Roep
Program.cs
in aan om de Middleware voor uitzonderingsafhandeling toe te voegen:var app = builder.Build(); app.UseHttpsRedirection(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/error"); } app.UseAuthorization(); app.MapControllers(); app.Run();
Configureer een controlleractie om te reageren op de
/error
route:[Route("/error")] public IActionResult HandleError() => Problem();
Met de voorgaande HandleError
actie wordt een rfC 7807-compatibele nettolading naar de client verzonden.
Warning
Markeer de actiemethode voor de fouthandler niet met HTTP-methodekenmerken, zoals HttpGet
. Expliciete werkwoorden voorkomen dat sommige aanvragen de actiemethode bereiken.
Voor web-API's die gebruikmaken van Swagger/OpenAPI, markeert u de actie fouthandler met het kenmerk [ApiExplorerSettings] en stelt u de eigenschap in IgnoreApi op true
. Deze kenmerkconfiguratie sluit de actie fouthandler uit van de OpenAPI-specificatie van de app:
[ApiExplorerSettings(IgnoreApi = true)]
Anonieme toegang tot de methode toestaan als niet-geverifieerde gebruikers de fout moeten zien.
Middleware voor uitzonderingsafhandeling kan ook worden gebruikt in de ontwikkelomgeving om een consistente payload-indeling te produceren in alle omgevingen:
Program.cs
Registreer omgevingsspecifieke Middleware-exemplaren voor uitzonderingsafhandeling:if (app.Environment.IsDevelopment()) { app.UseExceptionHandler("/error-development"); } else { app.UseExceptionHandler("/error"); }
In de voorgaande code wordt de middleware geregistreerd bij:
- Een route van
/error-development
in de ontwikkelomgeving. - Een route van
/error
niet-ontwikkelomgevingen.
- Een route van
Controlleracties toevoegen voor zowel de ontwikkelings- als niet-ontwikkelingsroutes:
[Route("/error-development")] public IActionResult HandleErrorDevelopment( [FromServices] IHostEnvironment hostEnvironment) { if (!hostEnvironment.IsDevelopment()) { return NotFound(); } var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>()!; return Problem( detail: exceptionHandlerFeature.Error.StackTrace, title: exceptionHandlerFeature.Error.Message); } [Route("/error")] public IActionResult HandleError() => Problem();
Uitzonderingen gebruiken om het antwoord te wijzigen
De inhoud van het antwoord kan worden gewijzigd van buiten de controller met behulp van een aangepaste uitzondering en een actiefilter:
Maak een bekend uitzonderingstype met de naam
HttpResponseException
:public class HttpResponseException : Exception { public HttpResponseException(int statusCode, object? value = null) => (StatusCode, Value) = (statusCode, value); public int StatusCode { get; } public object? Value { get; } }
Maak een actiefilter met de naam
HttpResponseExceptionFilter
:public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter { public int Order => int.MaxValue - 10; public void OnActionExecuting(ActionExecutingContext context) { } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception is HttpResponseException httpResponseException) { context.Result = new ObjectResult(httpResponseException.Value) { StatusCode = httpResponseException.StatusCode }; context.ExceptionHandled = true; } } }
Het voorgaande filter geeft een
Order
van de maximumwaarde voor gehele getallen min 10 op. HierdoorOrder
kunnen andere filters aan het einde van de pijplijn worden uitgevoerd.Voeg
Program.cs
in het actiefilter het volgende toe aan de verzameling filters:builder.Services.AddControllers(options => { options.Filters.Add<HttpResponseExceptionFilter>(); });
Foutreactie bij validatiefout
Voor web-API-controllers reageert MVC met een ValidationProblemDetails antwoordtype wanneer modelvalidatie mislukt. MVC gebruikt de resultaten van het samenstellen van InvalidModelStateResponseFactory de foutreactie voor een validatiefout. In het volgende voorbeeld wordt de standaardfactory vervangen door een implementatie die ook ondersteuning biedt voor het opmaken van antwoorden als XML, in Program.cs
:
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
new BadRequestObjectResult(context.ModelState)
{
ContentTypes =
{
// using static System.Net.Mime.MediaTypeNames;
Application.Json,
Application.Xml
}
};
})
.AddXmlSerializerFormatters();
Antwoord van clientfout
Er wordt een foutresultaat gedefinieerd als resultaat met een HTTP-statuscode van 400 of hoger. Voor web-API-controllers transformeert MVC een foutresultaat om een ProblemDetails.
De foutreactie kan op een van de volgende manieren worden geconfigureerd:
ProblemDetailsFactory
implementeren
MVC gebruikt Microsoft.AspNetCore.Mvc.Infrastructure.ProblemDetailsFactory om alle exemplaren van ProblemDetails en ValidationProblemDetails. Deze fabriek wordt gebruikt voor:
- Clientfoutreacties
- Foutreacties bij validatiefouten
- ControllerBase.Problem en ControllerBase.ValidationProblem
Registreer een aangepaste implementatie van ProblemDetailsFactory :Program.cs
builder.Services.AddControllers();
builder.Services.AddTransient<ProblemDetailsFactory, SampleProblemDetailsFactory>();
Gebruik ApiBehaviorOptions.ClientErrorMapping
Gebruik de ClientErrorMapping eigenschap om de inhoud van het ProblemDetails
antwoord te configureren. Met de volgende code wordt Program.cs
bijvoorbeeld de Link eigenschap bijgewerkt voor 404-antwoorden:
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
});
Aangepaste middleware voor het afhandelen van uitzonderingen
De standaardinstellingen in de uitzondering die middleware verwerken, werken goed voor de meeste apps. Voor apps waarvoor speciale afhandeling van uitzonderingen is vereist, kunt u overwegen om de middleware voor het verwerken van uitzonderingen aan te passen.
Een ProblemDetails-payload genereren voor uitzonderingen
ASP.NET Core produceert geen gestandaardiseerde foutpayload wanneer er een onverwerkte uitzondering optreedt. Voor scenario's waarin het wenselijk is om een gestandaardiseerde ProblemDetails-reactie op de client te retourneren, kan de MiddleWare ProblemDetails worden gebruikt om uitzonderingen en 404 antwoorden toe te wijzen aan een payload van ProblemDetails . De middleware voor het verwerken van uitzonderingen kan ook worden gebruikt om een ProblemDetails nettolading te retourneren voor niet-verwerkte uitzonderingen.
Additional resources
In dit artikel wordt beschreven hoe u foutafhandeling kunt afhandelen en aanpassen met ASP.NET Core-web-API's.
Voorbeeldcode weergeven of downloaden (downloaden)
Uitzonderingspagina voor ontwikkelaars
De uitzonderingspagina voor ontwikkelaars is een handig hulpprogramma om gedetailleerde stacktraceringen voor serverfouten op te halen. Het maakt gebruik DeveloperExceptionPageMiddleware van het vastleggen van synchrone en asynchrone uitzonderingen van de HTTP-pijplijn en voor het genereren van foutreacties. Bekijk ter illustratie de volgende controlleractie:
[HttpGet("{city}")]
public WeatherForecast Get(string city)
{
if (!string.Equals(city?.TrimEnd(), "Redmond", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException(
$"We don't offer a weather forecast for {city}.", nameof(city));
}
return GetWeather().First();
}
Voer de volgende curl
opdracht uit om de voorgaande actie te testen:
curl -i https://localhost:5001/weatherforecast/chicago
Op de uitzonderingspagina voor ontwikkelaars wordt een antwoord zonder opmaak weergegeven als de client geen UITVOER met HTML-indeling aanvraagt. De volgende uitvoer wordt weergegeven:
HTTP/1.1 500 Internal Server Error
Transfer-Encoding: chunked
Content-Type: text/plain
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Fri, 27 Sep 2019 16:13:16 GMT
System.ArgumentException: We don't offer a weather forecast for chicago. (Parameter 'city')
at WebApiSample.Controllers.WeatherForecastController.Get(String city) in C:\working_folder\aspnet\AspNetCore.Docs\aspnetcore\web-api\handle-errors\samples\3.x\Controllers\WeatherForecastController.cs:line 34
at lambda_method(Closure , Object , Object[] )
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
HEADERS
=======
Accept: */*
Host: localhost:44312
User-Agent: curl/7.55.1
Als u in plaats daarvan een html-opgemaakt antwoord wilt weergeven, stelt u de Accept
HTTP-aanvraagheader in op het text/html
mediatype. For example:
curl -i -H "Accept: text/html" https://localhost:5001/weatherforecast/chicago
Bekijk het volgende fragment uit het HTTP-antwoord:
HTTP/1.1 500 Internal Server Error
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Fri, 27 Sep 2019 16:55:37 GMT
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Internal Server Error</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Arial, Helvetica, sans-serif;
font-size: .813em;
color: #222;
background-color: #fff;
}
Het HTML-opgemaakte antwoord wordt nuttig bij het testen via hulpprogramma's zoals curl.
Warning
Schakel de uitzonderingspagina voor ontwikkelaars alleen in wanneer de app wordt uitgevoerd in de ontwikkelomgeving. Deel geen gedetailleerde uitzonderingsgegevens openbaar wanneer de app in productie wordt uitgevoerd. Zie Meerdere omgevingen gebruiken in ASP.NET Core voor meer informatie over het configureren van omgevingen.
Markeer de actiemethode voor de fouthandler niet met HTTP-methodekenmerken, zoals HttpGet
. Expliciete werkwoorden voorkomen dat sommige aanvragen de actiemethode bereiken. Anonieme toegang tot de methode toestaan als niet-geverifieerde gebruikers de fout moeten zien.
Exception handler
In niet-ontwikkelomgevingen kan Middleware voor uitzonderingsafhandeling worden gebruikt om een foutnlading te produceren:
UseExceptionHandler Roep in
Startup.Configure
aan om de middleware te gebruiken:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/error"); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
Configureer een controlleractie om te reageren op de
/error
route:[ApiController] public class ErrorController : ControllerBase { [Route("/error")] public IActionResult Error() => Problem(); }
Met de voorgaande Error
actie wordt een rfC 7807-compatibele nettolading naar de client verzonden.
Middleware voor het verwerken van uitzonderingen kan ook gedetailleerdere inhoudsonderhandelde uitvoer bieden in de lokale ontwikkelomgeving. Gebruik de volgende stappen om een consistente payload-indeling te maken in ontwikkel- en productieomgevingen:
Startup.Configure
Registreer omgevingsspecifieke Middleware-exemplaren voor uitzonderingsafhandeling:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseExceptionHandler("/error-local-development"); } else { app.UseExceptionHandler("/error"); } }
In de voorgaande code wordt de middleware geregistreerd bij:
- Een route van
/error-local-development
in de ontwikkelomgeving. - Een route van
/error
omgevingen die geen ontwikkeling zijn.
- Een route van
Kenmerkroutering toepassen op controlleracties:
[ApiController] public class ErrorController : ControllerBase { [Route("/error-local-development")] public IActionResult ErrorLocalDevelopment( [FromServices] IWebHostEnvironment webHostEnvironment) { if (webHostEnvironment.EnvironmentName != "Development") { throw new InvalidOperationException( "This shouldn't be invoked in non-development environments."); } var context = HttpContext.Features.Get<IExceptionHandlerFeature>(); return Problem( detail: context.Error.StackTrace, title: context.Error.Message); } [Route("/error")] public IActionResult Error() => Problem(); }
De voorgaande code roept ControllerBase.Problem aan om een ProblemDetails antwoord te maken.
Uitzonderingen gebruiken om het antwoord te wijzigen
De inhoud van het antwoord kan worden gewijzigd van buiten de controller. In ASP.NET web-API van 4.x is dit een manier om dit te doen.HttpResponseException ASP.NET Core bevat geen equivalent type. Ondersteuning voor HttpResponseException
kan worden toegevoegd met de volgende stappen:
Maak een bekend uitzonderingstype met de naam
HttpResponseException
:public class HttpResponseException : Exception { public int Status { get; set; } = 500; public object Value { get; set; } }
Maak een actiefilter met de naam
HttpResponseExceptionFilter
:public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter { public int Order { get; } = int.MaxValue - 10; public void OnActionExecuting(ActionExecutingContext context) { } public void OnActionExecuted(ActionExecutedContext context) { if (context.Exception is HttpResponseException exception) { context.Result = new ObjectResult(exception.Value) { StatusCode = exception.Status, }; context.ExceptionHandled = true; } } }
Het voorgaande filter geeft een
Order
van de maximumwaarde voor gehele getallen min 10 op. HierdoorOrder
kunnen andere filters aan het einde van de pijplijn worden uitgevoerd.Voeg
Startup.ConfigureServices
in het actiefilter het volgende toe aan de verzameling filters:services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter()));
Foutreactie bij validatiefout
Voor web-API-controllers reageert MVC met een ValidationProblemDetails antwoordtype wanneer modelvalidatie mislukt. MVC gebruikt de resultaten van het samenstellen van InvalidModelStateResponseFactory de foutreactie voor een validatiefout. In het volgende voorbeeld wordt de fabriek gebruikt om het standaardantwoordtype te SerializableError wijzigen in Startup.ConfigureServices
:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var result = new BadRequestObjectResult(context.ModelState);
// TODO: add `using System.Net.Mime;` to resolve MediaTypeNames
result.ContentTypes.Add(MediaTypeNames.Application.Json);
result.ContentTypes.Add(MediaTypeNames.Application.Xml);
return result;
};
});
Antwoord van clientfout
Er wordt een foutresultaat gedefinieerd als resultaat met een HTTP-statuscode van 400 of hoger. Voor web-API-controllers transformeert MVC een foutresultaat naar een resultaat met ProblemDetails.
De foutreactie kan op een van de volgende manieren worden geconfigureerd:
ProblemDetailsFactory
implementeren
MVC gebruikt Microsoft.AspNetCore.Mvc.Infrastructure.ProblemDetailsFactory om alle exemplaren van ProblemDetails en ValidationProblemDetails. Deze fabriek wordt gebruikt voor:
- Clientfoutreacties
- Foutreacties bij validatiefouten
- ControllerBase.Problem en ControllerBase.ValidationProblem
Registreer een aangepaste implementatie van ProblemDetailsFactory :Startup.ConfigureServices
public void ConfigureServices(IServiceCollection serviceCollection)
{
services.AddControllers();
services.AddTransient<ProblemDetailsFactory, CustomProblemDetailsFactory>();
}
Use ApiBehaviorOptions.ClientErrorMapping
Gebruik de ClientErrorMapping eigenschap om de inhoud van het ProblemDetails
antwoord te configureren. Met de volgende code wordt Startup.ConfigureServices
bijvoorbeeld de type
eigenschap bijgewerkt voor 404-antwoorden:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
});
Aangepaste middleware voor het afhandelen van uitzonderingen
De standaardinstellingen in de uitzondering die middleware verwerken, werken goed voor de meeste apps. Voor apps waarvoor speciale afhandeling van uitzonderingen is vereist, kunt u overwegen om de middleware voor het verwerken van uitzonderingen aan te passen.
Een ProblemDetails-nettolading voor uitzonderingen maken
ASP.NET Core produceert geen gestandaardiseerde foutpayload wanneer er een onverwerkte uitzondering optreedt. Voor scenario's waarin het wenselijk is om een gestandaardiseerde ProblemDetails-reactie op de client te retourneren, kan de MiddleWare ProblemDetails worden gebruikt om uitzonderingen en 404 antwoorden toe te wijzen aan een payload van ProblemDetails . De middleware voor het verwerken van uitzonderingen kan ook worden gebruikt om een ProblemDetails nettolading te retourneren voor niet-verwerkte uitzonderingen.