Получение сведений об ошибке из WCF REST
У меня есть служба REST, потребляемая клиентом.Net WCF.
При обнаружении ошибки служба REST возвращает неверный запрос HTTP 400 с телом ответа, содержащим сериализованные данные JSON.
Если я выполняю запрос, используя Fiddler, Javascript или непосредственно из C#, я могу легко получить доступ к телу ответа при возникновении ошибки.
Тем не менее, я использую WCF ChannelFactory
с 6 довольно сложными интерфейсами. Исключение, выбрасываемое этим прокси, всегда ProtocolException
, без полезных подробностей.
Есть ли способ получить тело ответа, когда я получаю эту ошибку?
Обновить
Я понимаю, что существует множество различных способов сделать это с помощью.Net и что есть другие способы получить ответ об ошибке. Их полезно знать, но не отвечайте на этот вопрос.
Службы REST, которые мы используем, изменятся, и когда они сделают, сложные интерфейсы будут обновлены. С использованием ChannelFactory
с новыми интерфейсами означает, что мы получим исключения во время компиляции (а не во время выполнения) и сделаем их намного проще для поддержки и обновления кода.
Есть ли способ получить тело ответа для состояния HTTP ошибки при использовании каналов WCF?
6 ответов
Не используйте 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>()
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();
Вы можете получить подробную информацию об исключении, как показано ниже:
Exception innerException = exception.InnerException;
WebException webException = innerException as WebException;
HttpWebResponse response = webException.Response as HttpWebResponse;
string statusDescription = response.StatusDescription;
HttpStatusCode statusCode = response.StatusCode;
Вы можете попробовать выбросить исключение WebProtocolException из службы. Таким образом, сведения об ошибке должны быть включены в тело HTTP-ответа. Посмотрите на эту статью:
Мои два цента в том, что WCF хорошо показывает один и тот же класс, используя много разных привязок. При взаимодействии с C# используйте привязку SOAP, которая хороша для информации об исключениях. Если вы должны использовать привязку стиля REST, вы можете использовать простой WebRequest для вызова службы и использовать сериализатор JSON для десериализации результатов. Это также даст вам прямой доступ к коду ответа.
Подход, описанный пользователем 653761, работает для меня; после доступа к HttpWebResponse
объект, который я могу использовать DataContractSerializer
класс как это:
var serializer = new DataContractSerializer(typeof(MyDataContractType));
var deserialized =
(serializer.ReadObject(httpWebResponse.GetResponseStream()) as MyDataContractType);
// ...
Я полагаю, что это сработает для всего, что WCF может сериализовать, если вы используете правильный сериализатор, не проверенный на производительность (пока).