В преддверии старта курса «C# ASP.NET Core разработчик» подготовили традиционный перевод полезного материала.
Также рекомендуем посмотреть вебинар на тему «Отличия структурных шаблонов проектирования на примерах». На этом открытом уроке участники вместе с преподавателем-экспертом познакомятся с тремя структурными шаблонами проектирования: Заместитель, Адаптер и Декоратор.
Введение
Сегодня в этой статье мы обсудим концепцию обработки исключений в приложениях ASP.NET Core. Обработка исключений (exception handling) — одна из наиболее важных импортируемых функций или частей любого типа приложений, которой всегда следует уделять внимание и правильно реализовывать. Исключения — это в основном средства ориентированные на обработку рантайм ошибок, которые возникают во время выполнения приложения. Если этот тип ошибок не обрабатывать должным образом, то приложение будет остановлено в результате их появления.
В ASP.NET Core концепция обработки исключений подверглась некоторым изменениям, и теперь она, если можно так сказать, находится в гораздо лучшей форме для внедрения обработки исключений. Для любых API-проектов реализация обработки исключений для каждого действия будет отнимать довольно много времени и дополнительных усилий. Но мы можем реализовать глобальный обработчик исключений (Global Exception handler), который будет перехватывать все типы необработанных исключений. Преимущество реализации глобального обработчика исключений состоит в том, что нам нужно определить его всего лишь в одном месте. Через этот обработчик будет обрабатываться любое исключение, возникающее в нашем приложении, даже если мы объявляем новые методы или контроллеры. Итак, в этой статье мы обсудим, как реализовать глобальную обработку исключений в ASP.NET Core Web API.
Создание проекта ASP.NET Core Web API в Visual Studio 2019
Итак, прежде чем переходить к обсуждению глобального обработчика исключений, сначала нам нужно создать проект ASP.NET Web API. Для этого выполните шаги, указанные ниже.
-
Откройте Microsoft Visual Studio и нажмите «Create a New Project» (Создать новый проект).
-
В диалоговом окне «Create New Project» выберите «ASP.NET Core Web Application for C#» (Веб-приложение ASP.NET Core на C#) и нажмите кнопку «Next» (Далее).
-
В окне «Configure your new project» (Настроить новый проект) укажите имя проекта и нажмите кнопку «Create» (Создать).
-
В диалоговом окне «Create a New ASP.NET Core Web Application» (Создание нового веб-приложения ASP.NET Core) выберите «API» и нажмите кнопку «Create».
-
Убедитесь, что флажки «Enable Docker Support» (Включить поддержку Docker) и «Configure for HTTPS» (Настроить под HTTPS) сняты. Мы не будем использовать эти функции.
-
Убедитесь, что выбрано «No Authentication» (Без аутентификации), поскольку мы также не будем использовать аутентификацию.
-
Нажмите ОК.
Используем UseExceptionHandler middleware в ASP.NET Core.
Чтобы реализовать глобальный обработчик исключений, мы можем воспользоваться преимуществами встроенного Middleware ASP.NET Core. Middleware представляет из себя программный компонент, внедренный в конвейер обработки запросов, который каким-либо образом обрабатывает запросы и ответы. Мы можем использовать встроенное middleware ASP.NET Core UseExceptionHandler в качестве глобального обработчика исключений. Конвейер обработки запросов ASP.NET Core включает в себя цепочку middleware-компонентов. Эти компоненты, в свою очередь, содержат серию делегатов запросов, которые вызываются один за другим. В то время как входящие запросы проходят через каждый из middleware-компонентов в конвейере, каждый из этих компонентов может либо обработать запрос, либо передать запрос следующему компоненту в конвейере.
С помощью этого middleware мы можем получить всю детализированную информацию об объекте исключения, такую как стектрейс, вложенное исключение, сообщение и т. д., а также вернуть эту информацию через API в качестве вывода. Нам нужно поместить middleware обработки исключений в configure()
файла startup.cs
. Если мы используем какое-либо приложение на основе MVC, мы можем использовать middleware обработки исключений, как это показано ниже. Этот фрагмент кода демонстрирует, как мы можем настроить middleware UseExceptionHandler
для перенаправления пользователя на страницу с ошибкой при возникновении любого типа исключения.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseExceptionHandler("/Home/Error"); app.UseMvc(); }
Теперь нам нужно проверить сообщение об исключении. Для этого откройте файл WeatherForecastController.cs
и добавьте следующий экшн-метод, чтобы пробросить исключение:
[Route("GetExceptionInfo")] [HttpGet] public IEnumerable<string> GetExceptionInfo() { string[] arrRetValues = null; if (arrRetValues.Length > 0) { } return arrRetValues; }
Если мы хотим получить подробную информацию об объектах исключения, например, стектрейс, сообщение и т. д., мы можем использовать приведенный ниже код в качестве middleware исключения —
app.UseExceptionHandler( options => { options.Run( async context => { context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; context.Response.ContentType = "text/html"; var exceptionObject = context.Features.Get<IExceptionHandlerFeature>(); if (null != exceptionObject) { var errorMessage = $"<b>Exception Error: {exceptionObject.Error.Message} </b> {exceptionObject.Error.StackTrace}"; await context.Response.WriteAsync(errorMessage).ConfigureAwait(false); } }); } );
Для проверки вывода просто запустите эндпоинт API в любом браузере:
Определение пользовательского Middleware для обработки исключений в API ASP.NET Core
Кроме того, мы можем написать собственное middleware
для обработки любых типов исключений. В этом разделе мы продемонстрируем, как создать типичный пользовательский класс middleware
. Пользовательское middleware
также обеспечивает гораздо большую гибкость для обработки исключений. Мы можем добавить стекатрейс, имя типа исключения, код ошибки или что-нибудь еще, что мы захотим включить как часть сообщения об ошибке. В приведенном ниже фрагменте кода показан типичный пользовательский класс middleware
:
using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; namespace API.DemoSample.Exceptions { public class ExceptionHandlerMiddleware { private readonly RequestDelegate _next; public ExceptionHandlerMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { try { await _next.Invoke(context); } catch (Exception ex) { } } } }
В приведенном выше классе делегат запроса передается любому middleware
. Middleware
либо обрабатывает его, либо передает его следующему middleware
в цепочке. Если запрос не успешен, будет выброшено исключение, а затем будет выполнен метод HandleExceptionMessageAsync
в блоке catch
. Итак, давайте обновим код метода Invoke
, как показано ниже:
public async Task Invoke(HttpContext context) { try { await _next.Invoke(context); } catch (Exception ex) { await HandleExceptionMessageAsync(context, ex).ConfigureAwait(false); } }
Теперь нам нужно реализовать метод HandleExceptionMessageAsync
, как показано ниже:
private static Task HandleExceptionMessageAsync(HttpContext context, Exception exception) { context.Response.ContentType = "application/json"; int statusCode = (int)HttpStatusCode.InternalServerError; var result = JsonConvert.SerializeObject(new { StatusCode = statusCode, ErrorMessage = exception.Message }); context.Response.ContentType = "application/json"; context.Response.StatusCode = statusCode; return context.Response.WriteAsync(result); }
Теперь, на следующем шаге, нам нужно создать статический класс с именем ExceptionHandlerMiddlewareExtensions
и добавить приведенный ниже код в этот класс,
using Microsoft.AspNetCore.Builder; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace API.DemoSample.Exceptions { public static class ExceptionHandlerMiddlewareExtensions { public static void UseExceptionHandlerMiddleware(this IApplicationBuilder app) { app.UseMiddleware<ExceptionHandlerMiddleware>(); } } }
На последнем этапе, нам нужно включить наше пользовательское middleware в методе Configure класса startup, как показано ниже:
app.UseExceptionHandlerMiddleware();
Заключение
Обработка исключений — это по сути сквозная функциональность для любого типа приложений. В этой статье мы обсудили процесс реализации концепции глобальной обработки исключений. Мы можем воспользоваться преимуществами глобальной обработки исключений в любом приложении ASP.NET Core, чтобы гарантировать, что каждое исключение будет перехвачено и вернет правильные сведения, связанные с этим исключением. С глобальной обработкой исключений нам достаточно в одном месте написать код, связанный с обработкой исключений, для всего нашего приложения. Любые предложения, отзывы или запросы, связанные с этой статьей, приветствуются.
Узнать подробнее о курсе «C# ASP.NET Core разработчик».
Посмотреть вебинар на тему «Отличия структурных шаблонов проектирования на примерах».
ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/543390/
Добавить комментарий