Служба REST WCF с IErrorHandler перехватывает исключения SerializationExceptions
У меня есть служба REST WCF с пользовательским IErrorHandler, так что я могу перехватить все неперехваченные исключения в моем сервисе, вернуть собственное сообщение об ошибке, правильный код статуса Http (500) и записать ошибку.
Проблема в том, что IErrorHandler будет перехватывать исключения, не происходящие из моего кода, поэтому, если я, например, сделаю POST для службы с недопустимыми данными JSON, я получу исключение SerializationException. Это исключение было бы преобразовано в исключение WebFaultException с кодом состояния BadRequest 400, если бы не мой IErrorHandler, где я буду обрабатывать его так же, как и все другие неперехваченные исключения.
Есть ли способ справиться с этими ситуациями или я должен просто перехватить исключения SerializationExceptions в моем IErrorHandler и установить там BadRequest? Какие другие исключения могут возникать из стека WCF без использования моего кода?
Обновление: добавлена моя реализация IErrorHandler.ProvideFault
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
Guid loggingId = Guid.NewGuid();
error.Data["ExceptionLoggingId"] = loggingId;
if (error is SecurityTokenException)
{
fault = Message.CreateMessage(version, string.Empty, String.Format("{0}. The error identifier is {1}", error.Message, loggingId), new DataContractJsonSerializer(typeof(string)));
fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
webOperationContextWrapper.SetOutgoingResponseStatusCode(HttpStatusCode.Unauthorized);
}
else
{
if (error is SerializationException)
{
// TODO: What if the SerializationException originates from within the service?
// SerializationException due to malformed JSON
return;
}
fault = Message.CreateMessage(version, string.Empty, String.Format("An unknown error has occurred. The error identifier is {0}", loggingId), new DataContractJsonSerializer(typeof(string)));
fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
webOperationContextWrapper.SetOutgoingResponseStatusCode(HttpStatusCode.InternalServerError);
}
}
2 ответа
Я столкнулся с аналогичной проблемой.
Мое решение состояло в том, чтобы использовать пространство имен для определения источника исключения.
if (!error.StackTrace.TrimStart().StartsWith("at " + this.GetType().Namespace.Split('.')[0]))
return;
Это работает в моем текущем проекте. Но в зависимости от вашего проекта, это может не...
Я думаю, что Richard Blewett это правильно. Вы захотите создать собственный класс исключений и выдать его, проверить этот тип в обработчике ошибок, а затем позволить стандартному исключению сериализации проходить нормально. Это кажется лучшим дизайном для меня.
Затем вы получите безопасное исключение типа, которое, если вы удалите или измените, код обработчика ошибок не скомпилируется или будет подвергнут рефакторингу с типом, если вы сделаете это через VS. Подобное тестирование пространства имен, вероятно, будет менее чем целесообразно (хотя и очень умно), поскольку оно напрямую не связано с каким-либо типом во время компиляции. Если вы измените пространство имен вокруг, вы столкнетесь с проблемой, которую трудно отследить.