Как заблокировать исключение 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, который будет регистрировать исключения, возникающие во время сериализации. Но да, если вы не знаете о запросах, которые вызывают ошибки в сериализации, тогда вы можете включить трассировку все время, которое я не уверен, это то, что вы, возможно, захотите сделать.