Получение информации об ошибке из WCF REST

У меня есть служба REST, потребляемая клиентом .NET WCF.

При возникновении ошибки служба REST возвращает ошибочный запрос HTTP 400 с телом ответа, содержащим детализированные JSON-данные.

Если я выполняю запрос с помощью Fiddler, Javascript или непосредственно с С#, я могу легко получить доступ к телу ответа при возникновении ошибки.

Однако я использую WCF ChannelFactory с 6 довольно сложными интерфейсами. Исключение, созданное этим прокси-сервером, всегда равно ProtocolException, без каких-либо полезных сведений.

Есть ли способ получить тело ответа, когда я получаю эту ошибку?


Обновление

Я понимаю, что есть много разных способов сделать это, используя .Net и что есть другие способы получить ответ об ошибке. Они полезны, но не отвечают на этот вопрос.

Службы REST, которые мы используем, будут меняться, и когда они будут обрабатывать сложные интерфейсы. Использование ChannelFactory с новыми интерфейсами означает, что мы получим исключения времени компиляции (а не времени выполнения) и упростим их обновление и обновление кода.

Есть ли способ получить тело ответа для HTTP-статуса ошибки при использовании каналов WCF?

Ответы

Ответ 1

Не используйте ChannelFactory:-) Серьезно. Зачем вам создавать REST-интерфейс, а затем использовать прокси-сервер WCF-клиента. В чем преимущество использования службы REST? Почему бы просто не использовать wsHttpBinding? С классом HttpClient из стартового набора REST вы можете создавать стандартные HTTP-запросы и затем десериализовать ответ с помощью DataContractSerializer.

например.

var httpClient = new HttpClient();
var content = httpClient.Get("http://example.org/customer/45").Content;
var customer = content.ReadAsDataContract<Customer>()

Ответ 2

вы можете получить подробную информацию об исключении, как показано ниже:

                Exception innerException = exception.InnerException;
                WebException webException = innerException as WebException;
                HttpWebResponse response = webException.Response as HttpWebResponse;
                string statusDescription = response.StatusDescription;
                HttpStatusCode statusCode = response.StatusCode;

Ответ 3

Вы можете попробовать сбросить WebProtocolException из службы. Таким образом, сведения об ошибке должны быть включены в тело ответа HTTP. Взгляните на эту статью:

Эффективная обработка ошибок с WCF и REST

Ответ 4

InnerException ProtocolException будет WebException. Вы можете получить HttpWebResponse от этого и вызвать GetResponseStream, чтобы прочитать фактическое тело ответа. (Не забудьте найти начало потока перед чтением).

var webException = (WebException) protocolException.InnerException;
var response = (HttpWebResponse) webException.Response;
var responseStream = response.GetResponseStream()
responseStream.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(responseStream);
var responseContent = reader.ReadToEnd();

Ответ 5

Мои два цента - это то, что WCF хорошо разоблачает один и тот же класс, используя множество разных привязок. При общении с С# используйте привязку SOAP, которая хороша для информации об исключении. Если вы должны использовать привязку стиля REST, вы можете использовать простой WebRequest для вызова службы и использовать сериализатор JSON для десериализации результатов. Это также даст вам прямой доступ к коду ответа.

Ответ 6

Подход, описанный пользователем653761, работает для меня; после доступа к объекту HttpWebResponse я могу использовать класс DataContractSerializer следующим образом:

var serializer = new DataContractSerializer(typeof(MyDataContractType));
var deserialized = 
    (serializer.ReadObject(httpWebResponse.GetResponseStream()) as MyDataContractType);

// ...

Я предполагаю, что это сработает для всего, что WCF может сериализовать, если вы используете правильный сериализатор, не тестировали производительность (пока).