Получение информации об ошибке из 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 может сериализовать, если вы используете правильный сериализатор, не тестировали производительность (пока).