Улучшения Problem Details в ASP.NET 9
В ASP.NET 8 улучшили обработку исключений, представив IExceptionHandler. В ASP.NET 9 промежуточное ПО обработчика исключений было улучшено для обеспечения большей гибкости и контроля над кодом статуса ответа при использовании Problem Details.
Problem Details становится стандартизированным способом представления информации об ошибках в ответе HTTP API. ASP.NET уже поддерживает Problem Details, но вам нужно включить его. Это можно сделать, зарегистрировав промежуточное ПО Problem Details:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
// Возвращаем страницы с ответом при неудаче
// По умолчанию возвращается пустое тело со статусом
app.UseStatusCodePages();
// Переводим ошибки в ответы Problem Details
app.UseExceptionHandler();
app.Run();
AddProblemDetails в сочетании с UseStatusCodePages достаточно для возврата ответов Problem Details для конечных точек, которые возвращают пустой неуспешный ответ (например, BadRequest). Если конечная точка возвращает неуспешный ответ с телом, это тело будет возвращено. Метод UseExceptionHandler преобразует исключения времени выполнения, возникшие при выполнении конечной точки, в ответы соответствующие формату Problem Details:
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.6.1",
"title": "An error occurred while processing your request.",
"status": 500,
"traceId": "00-f942c075462cb925f9f1820ce659036a-9a6b9ad75bfcbf22-00"
}Без UseExceptionHandler API просто вернёт статус 500 без тела.
Ответы Problem Details можно настраивать, реализовав IExceptionHandler, чтобы предоставить больше информации пользователю. В ASP.NET 9 этот процесс упрощён.
Новое свойство конфигурации StatusCodeSelector делает пользовательскую реализацию обработчика исключений практически ненужной (в большинстве случаев). Вы можете использовать её для более сложных сценариев или для регистрации исключения. StatusCodeSelector позволяет изменять код состояния по умолчанию (500) на основе исключения:
// …
app.UseExceptionHandler(new ExceptionHandlerOptions
{
StatusCodeSelector = ex => ex switch {
UserNotAllowedException =>
StatusCodes.Status401Unauthorized,
UserNotFoundException =>
StatusCodes.Status403Forbidden,
NotImplementedException =>
StatusCodes.Status501NotImplemented,
_ => StatusCodes.Status500InternalServerError
}
});
// …
Так, если приложение выбросит ошибку UserNotFoundException, клиенту вернётся состояние 403 (Запрещено).
Если вы решите реализовать пользовательский обработчик исключений, вы по-прежнему можете использовать свойство StatusCodeSelector для установки кода состояния. Но, если StatusCode устанавливается обработчиком исключений, StatusCodeSelector игнорируется.
Итого
StatusCodeSelector позволяет легко менять код состояния по умолчанию (500) на основе типа исключения. Поскольку StatusCodeSelector принимает исключение, другие свойства исключения также могут использоваться для определения кода состояния.
Источник: https://timdeschryver.dev/blog/taking-a-look-at-the-problem-details-enhancements-in-aspnet-9