Как заблокировать исключение SerializationException в веб-API?

У меня есть веб-сервис ASP.NET Web API, который при определенных обстоятельствах бросает исключение SerializationException. Проблема в том, что я не могу ловить ловушку и регистрировать эту серверную часть исключения - единственное место, которое она обнаруживает, находится в теле ответа HTTP клиенту.

Я зарегистрировал ExceptionFilterAttribute, как описано в Обработка исключений в веб-интерфейсе ASP.NET, и подтвердил, что он работает правильно, когда я выбрал исключение внутри моего контроллера. К сожалению, исключение SerializationException выбрасывается во время ответа (после контроллера) и, похоже, полностью поглощено ASP.NET. Я также попытался подключить Application_Error() в Global.asax.cs, но он тоже не отображался.

Как я могу улавливать исключения SerializationException во время ответа веб-API?

Ответ 1

Если вместо возврата объекта вы используете метод ApiController.CreateResponse() и возвращаете HttpResponseMessage, вы можете сделать response.Content.LoadIntoBufferAsync().Wait(), и это заставит сериализацию произойти, пока вы все еще находитесь в действии и, следовательно, можете поймать исключение.

Ответ 2

Вы можете поймать все исключения Web Api, зарегистрировав реализацию IExceptionHandler.

См. Глобальная обработка ошибок веб-API

существует ряд случаев, когда обработчики исключений не могут обрабатывать. Например:

  • Исключения, созданные из конструкторов контроллера.
  • Исключения, брошенные из обработчиков сообщений.
  • Исключения, брошенные во время маршрутизации.
  • Исключения, возникающие при сериализации содержимого ответа.

Одна вещь, не упомянутая в этой статье, заключается в том, что ваш IExceptionHandler должен быть зарегистрирован через несколько случаев, когда обработчики исключений не могут обрабатывать. Например:

Exceptions thrown from controller constructors.
Exceptions thrown from message handlers.
Exceptions thrown during routing.
Exceptions thrown during response content serialization .

Одна вещь, не упомянутая в этой статье, заключается в том, что ваш IExceptionHandler должен быть зарегистрирован либо с помощью GlobalConfiguration.Configuration.Services.Add(...), либо через контейнер IoC, сконфигурированный для использования DependencyResolver.

Ответ 3

BTW, Сериализация ответов на самом деле происходит на уровнях хоста (в HttpControllerHandler, при размещении в IIS и в HttpSelfhostServer, при размещении в SelfHost), который находится ниже стека, а не сразу после ответа ответа от действия.

Плакат с плакатами WebAPI: http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster-grayscale.pdf

Тем не менее, я не могу придумать прямой способ достичь этого. Это громоздко, но может быть переопределить стандартные методы WriteToStreamAsync Xml и Json Formatter и просмотреть все исключения из журналов try-catch?

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