Литмир - Электронная Библиотека
A
A

На заметку! Фильтры — крайне мощное средство ASP.NET Core. В этой главе вы ознакомитесь только с фильтрами исключений, но с их помощью можно создавать очень многое, что значительно экономит время при построении приложений ASP.NET Core. Полную информацию о фильтрах ищите в документации по ссылке

https://docs.microsoft.com/ru-ru/aspnet/core/mvc/controllers/filters
.

Создание специального фильтра исключений

Создайте новый каталог под названием

Filters
и добавьте в него новый файл класса по имени
CustomExceptionFilterAttribute.cs
. Приведите операторы
using
к следующему виду:

using Microsoft.AspNetCore.Hosting;

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.Filters;

using Microsoft.EntityFrameworkCore;

using Microsoft.Extensions.Hosting;

Сделайте класс открытым и унаследованным от

ЕхсерtionFiIterAttribute
. Переопределите метод
OnException()
, как показано ниже:

namespace AutoLot.Api.Filters

{

  public class CustomExceptionFilterAttribute : ExceptionFilterAttribute

  {

    public override void OnException(ExceptionContext context)

    {

    }

  }

}

В отличие от большинства фильтров в ASP.NET Core, которые имеют обработчик событий "перед" и "после", фильтры исключений располагают только одним обработчиком:

OnException()
(или
OnExceptionAsync()
). Обработчик принимает один параметр,
ExceptionContext
, который предоставляет доступ к
ActionContext
, а также к сгенерированному исключению.

Кроме того, фильтры принимают участие во внедрении зависимостей, позволяя получить доступ в коде к любому элементу внутри контейнера. В рассматриваемом примере вам необходим экземпляр реализации

IWebHostEnvironment
, внедренный в фильтр, который будет использоваться для выяснения среды времени выполнения. Если средой является
Development
, тогда ответ должен также включать трассировку стека. Добавьте переменную уровня класса для хранения экземпляра реализации
IWebHostEnvironment
и конструктор:

private readonly IWebHostEnvironment _hostEnvironment;

public CustomExceptionFilterAttribute(IWebHostEnvironment hostEnvironment)

{

  _hostEnvironment = hostEnvironment;

}

Код в обработчике

OnException()
проверяет тип сгенерированного исключения и строит соответствующий ответ. В случае среды
Development
в сообщение ответа включается трассировка стека. Затем создается динамический объект, который содержит значения для отправки вызывающему запросу, и возвращается в
IActionResult
. Вот модифицированный код метода:

public override void OnException(ExceptionContext context)

{

  var ex = context.Exception;

   string stackTrace = _hostEnvironment.IsDevelopment()

     ? context.Exception.StackTrace :
string.Empty;

  string message = ex.Message;

  string error;

    IActionResult actionResult;

  switch (ex)

  {

    case DbUpdateConcurrencyException ce:

      // Возвращается код HTTP 400.

      error = "Concurrency Issue.";

      actionResult = new BadRequestObjectResult(

        new {Error = error, Message = message, StackTrace = stackTrace});

      break;

    default:

      error = "General Error.";

      actionResult = new ObjectResult(

        new {Error = error, Message = message, StackTrace = stackTrace})

      {

        StatusCode = 500

      };

      break;

  }

  //context.ExceptionHandled = true; // Если убрать здесь комментарий,

                                     // то исключение поглощается

  context.Result = actionResult;

}

Если вы хотите, чтобы фильтр исключений поглотил исключение и установил код состояния в 200 (скажем, для регистрации ошибки в журнале, не возвращая ее клиенту), тогда поместите следующую строку перед установкой

Result
(в предыдущем примере кода просто уберите комментарий):

context.ExceptionHandled = true;

Добавление фильтров в конвейер обработки

Фильтры можно применять к методам действий, контроллерам или глобально к приложению. Код "перед" фильтров выполняется снаружи вовнутрь (глобальный, контроллер, метод действия), в то время как код "после" фильтров выполняется изнутри наружу (метод действия, контроллер, глобальный).

На уровне приложения фильтры добавляются в методе

ConfigureServices()
класса
Startup
. Откройте файл класса
Startup.cs
и поместите в начало файла следующий оператор
using
:

using AutoLot.Api.Filters;

607
{"b":"847442","o":1}