Я использую ASP.NET Core для моего нового проекта API REST после использования обычного веб-API ASP.NET в течение многих лет. Я не вижу хорошего способа обработки исключений в ASP.NET Core Web API. Я попытался реализовать исключение фильтр / атрибут:
public class ErrorHandlingFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
HandleExceptionAsync(context);
context.ExceptionHandled = true;
}
private static void HandleExceptionAsync(ExceptionContext context)
{
var exception = context.Exception;
if (exception is MyNotFoundException)
SetExceptionResult(context, exception, HttpStatusCode.NotFound);
else if (exception is MyUnauthorizedException)
SetExceptionResult(context, exception, HttpStatusCode.Unauthorized);
else if (exception is MyException)
SetExceptionResult(context, exception, HttpStatusCode.BadRequest);
else
SetExceptionResult(context, exception, HttpStatusCode.InternalServerError);
}
private static void SetExceptionResult(
ExceptionContext context,
Exception exception,
HttpStatusCode code)
{
context.Result = new JsonResult(new ApiResponse(exception))
{
StatusCode = (int)code
};
}
}
И вот моя регистрация запуска фильтра:
services.AddMvc(options =>
{
options.Filters.Add(new AuthorizationFilter());
options.Filters.Add(new ErrorHandlingFilter());
});
Проблема, с которой я столкнулся, заключается в том, что когда возникает исключение, AuthorizationFilter
оно не обрабатывается ErrorHandlingFilter
. Я ожидал, что это будет поймано там точно так же, как это работало со старым ASP.NET Web API.
Итак, как я могу перехватить все исключения приложений, а также любые исключения из фильтров действий?
c#
exception
asp.net-core
Андрей
источник
источник
UseExceptionHandler
промежуточное ПО?UseExceptionHandler
промежуточноеОтветы:
Промежуточное ПО для обработки исключений
После многих экспериментов с различными подходами к обработке исключений я в конечном итоге использовал промежуточное ПО. Лучше всего сработало для моего приложения ASP.NET Core Web API. Он обрабатывает исключения приложений, а также исключения из фильтров действий, и у меня есть полный контроль над обработкой исключений и ответом HTTP. Вот мое промежуточное ПО для обработки исключений:
Зарегистрируйте это до MVC в
Startup
классе:Вы можете добавить трассировку стека, имя типа исключения, коды ошибок или все, что вы хотите. Очень гибкий Вот пример ответа об исключении:
Рассмотрим инъекционного
IOptions<MvcJsonOptions>
кInvoke
способу затем использовать его , когда вы сериализовать объект ответа для использования параметров сериализации ASP.NET MVC вJsonConvert.SerializeObject(errorObj, opts.Value.SerializerSettings)
для лучшей согласованности сериализации во всех конечных точках.Подход 2
Есть еще один неочевидный API, который называется
UseExceptionHandler
«хорошо» для простых сценариев:Это не очень очевидный, но простой способ настроить обработку исключений. Однако я все еще предпочитаю подход промежуточного программного обеспечения, так как я получаю больше контроля со способностью внедрять необходимые зависимости.
источник
app.UseMiddleware<ErrorHandlingMiddleware>();
в незадолго до этогоapp.UseStaticFiles();
. Кажется, что исключение теперь правильно уловлено. Это заставляет меня поверить в то, что нужноapp.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); app.UseBrowserLink();
сделать какую-то внутреннюю магическую хакерскую программу промежуточного программного обеспечения, чтобы правильно упорядочить промежуточное программное обеспечение.Последний
Asp.Net Core
(по крайней мере из 2.2, возможно, ранее) имеет встроенное промежуточное ПО, что делает его немного проще по сравнению с реализацией в принятом ответе:Он должен делать почти то же самое, просто немного меньше кода для написания.
Важно: не забудьте добавить его до
UseMvc
(илиUseRouting
в .Net Core 3), так как порядок важен.источник
Лучше всего использовать промежуточное программное обеспечение для ведения журнала, который вы ищете. Вы хотите поместить журнал исключений в одно промежуточное ПО, а затем обрабатывать отображаемые пользователю страницы ошибок в другом промежуточном ПО. Это позволяет разделить логику и следовать дизайну, который Microsoft разработал для двух компонентов промежуточного программного обеспечения. Вот хорошая ссылка на документацию Microsoft: Обработка ошибок в ASP.Net Core
Для вашего конкретного примера, вы можете использовать один из расширений в промежуточном StatusCodePage или свернуть свой собственный , как это .
Вы можете найти пример здесь для регистрации исключений: ExceptionHandlerMiddleware.cs
Если вам не нравится эта конкретная реализация, вы также можете использовать ELM Middleware , и вот несколько примеров: Elm Exception Middleware
Если это не работает для ваших нужд, вы всегда можете свернуть свой собственный компонент Middleware, взглянув на их реализации ExceptionHandlerMiddleware и ElmMiddleware, чтобы понять концепции для создания своих собственных.
Важно добавить промежуточное программное обеспечение для обработки исключений ниже промежуточного программного обеспечения StatusCodePages, но выше всех остальных компонентов промежуточного программного обеспечения. Таким образом, ваше промежуточное ПО Exception будет регистрировать исключение, зарегистрировать его, а затем разрешить запросу перейти к промежуточному программному обеспечению StatusCodePage, которое покажет пользователю дружественную страницу ошибок.
источник
UseStatusCodePages
это полезно в реализации сервиса Web API. Нет просмотров или HTML вообще, только ответы JSON ...Хорошо принятый ответ мне очень помог, но я хотел передать HttpStatusCode в свое промежуточное ПО для управления кодом состояния ошибки во время выполнения.
По этой ссылке у меня появилась идея сделать то же самое. Так что я слил Андрей Ответ с этим. Итак, мой окончательный код ниже:
1. Базовый класс
2. Пользовательский тип класса исключения
3. Промежуточное ПО для пользовательских исключений
4. Метод продления
5. Настройте метод в файле startup.cs.
Теперь мой метод входа в систему в учетной записи контроллера:
Выше вы можете увидеть, если я не нашел пользователя, то поднял исключение HttpStatusCodeException, в котором я передал статус HttpStatusCode.NotFound и пользовательское сообщение
в промежуточном ПО.
будет вызван заблокированный, который передаст управление
,
Но что, если я получил ошибку во время выполнения раньше? Для этого я использовал блок try catch, который генерирует исключение и будет перехвачен в блоке catch (Exception exceptionObj) и передаст управление
метод.
Я использовал один класс ErrorDetails для единообразия.
источник
startup.cs
вvoid Configure(IapplicationBuilder app)
я получаю ошибкуIApplicationBuilder does not contain a definition for ConfigureCustomExceptionMiddleware
. И я добавил ссылку, гдеCustomExceptionMiddleware.cs
находится.Чтобы настроить поведение обработки исключений для каждого типа исключения, вы можете использовать Middleware из пакетов NuGet:
ASP.NET Core 2.0
ASP.NET Core 2.1+
.Пример кода:
источник
Во-первых, спасибо Андрею, поскольку я основал свое решение на его примере.
Я включаю мой, так как это более полный пример и может сэкономить читателям время.
Ограничение подхода Андрея состоит в том, что он не обрабатывает ведение журнала, захват потенциально полезных переменных запроса и согласование содержимого (он всегда будет возвращать JSON независимо от того, что запросил клиент - XML / простой текст и т. Д.).
Мой подход заключается в использовании ObjectResult, который позволяет нам использовать функциональность, встроенную в MVC.
Этот код также предотвращает кеширование ответа.
Ответ об ошибке был оформлен таким образом, что сериализатор XML может его сериализовать.
источник
Сначала настройте ASP.NET Core 2
Startup
для повторного выполнения на странице ошибок для любых ошибок с веб-сервера и любых необработанных исключений.Затем определите тип исключения, который позволит вам выдавать ошибки с кодами состояния HTTP.
Наконец, в вашем контроллере для страницы ошибок настройте ответ на основании причины ошибки и того, будет ли ответ просматриваться непосредственно конечным пользователем. Этот код предполагает, что все URL-адреса API начинаются с
/api/
.ASP.NET Core запишет подробности ошибки, чтобы вы могли отладить их, поэтому код состояния может быть всем, что вы хотите предоставить (потенциально ненадежному) запрашивающему. Если вы хотите показать больше информации, вы можете улучшить
HttpException
ее. Для ошибок API вы можете поместить информацию об ошибке в кодировке JSON в тело сообщения, заменивreturn StatusCode...
наreturn Json...
.источник
используйте промежуточное ПО или IExceptionHandlerPathFeature - это нормально. в интернет- магазине есть другой путь
создать исключительный фильтр и зарегистрировать его
источник