Служба REST WCF с IErrorHandler перехватывает исключения SerializationExceptions - PullRequest
2 голосов
/ 18 июля 2011

У меня есть служба REST WCF с пользовательским IErrorHandler, так что я могу перехватить все неперехваченные исключения в моем сервисе, вернуть собственное сообщение об ошибке, правильный код статуса Http (500) и записать ошибку.

Проблема в том, что IErrorHandler будет перехватывать исключения, не происходящие из моего кода, поэтому, если я, например, сделаю POST для службы с недопустимыми данными JSON, я получу исключение SerializationException. Это исключение было бы преобразовано в исключение WebFaultException с кодом состояния BadRequest 400, если бы не мой IErrorHandler, где я буду обрабатывать его так же, как и все другие неперехваченные исключения.

Есть ли способ справиться с этими ситуациями или я должен просто перехватить исключения SerializationException в моем 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 ]

1 голос
/ 08 ноября 2011

Я столкнулся с подобной проблемой.

Моим решением было использование пространства имен для определения источника исключения.

if (!error.StackTrace.TrimStart().StartsWith("at " + this.GetType().Namespace.Split('.')[0]))
    return;

Это работает в моем текущем проекте. Но в зависимости от вашего проекта, это может не ...

0 голосов
/ 30 августа 2012

Я думаю, @ RichardBlewett правильно. Вы захотите создать собственный класс исключений и выдать его, проверить этот тип в обработчике ошибок и затем позволить стандартному исключению сериализации проходить нормально. Мне кажется, это лучший шаблон дизайна.

Затем вы получите безопасное исключение типа, которое, если вы удалите или измените, код обработчика ошибок не скомпилируется или будет изменен с типом, если вы сделаете это через VS. Подобное тестирование пространства имен, вероятно, будет менее чем целесообразно (хотя и очень умно), поскольку оно напрямую не связано с каким-либо типом во время компиляции. Если вы измените пространство имен вокруг, вы столкнетесь с проблемой, которую трудно отследить.

...