9

我有一个 .Net WCF 客户端使用的 REST 服务。

当遇到错误时,REST 服务会返回一个 HTTP 400 错误请求,其响应正文包含 JSON 序列化详细信息。

如果我使用 Fiddler、Javascript 或直接从 C# 执行请求,我可以在发生错误时轻松访问响应正文。

但是,我正在使用ChannelFactory具有 6 个非常复杂的接口的 WCF。这个代理抛出的异常总是 a ProtocolException,没有有用的细节。

当我收到此错误时,有什么方法可以获取响应正文?


更新

我意识到使用 .Net 有很多不同的方法可以做到这一点,并且还有其他方法可以获得错误响应。他们很有用,但不回答这个问题。

我们正在使用的 REST 服务会发生变化,并且当它们发生变化时,复杂的接口会得到更新。与新接口一起使用ChannelFactory意味着我们将获得编译时(而不是运行时)异常,并使这些更容易维护和更新代码。

使用 WCF 通道时,有什么方法可以获取错误 HTTP 状态的响应正文?

4

6 回答 6

5

您可以检索异常详细信息,如下所示:

                Exception innerException = exception.InnerException;
                WebException webException = innerException as WebException;
                HttpWebResponse response = webException.Response as HttpWebResponse;
                string statusDescription = response.StatusDescription;
                HttpStatusCode statusCode = response.StatusCode;
于 2011-03-10T15:05:22.510 回答
5

InnerExceptionProtocolException是一个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();
于 2014-01-07T09:50:40.263 回答
3

您可以尝试从服务中抛出WebProtocolException 。这样,错误详细信息应包含在 HTTP 响应的正文中。看看这篇文章:

使用 WCF 和 REST 进行有效的错误处理

于 2010-04-05T14:00:03.503 回答
1

不要认真使用 ChannelFactory :-)。为什么要创建一个 REST 接口,然后使用 WCF 客户端代理。使用 REST 服务有什么好处?为什么不直接使用 wsHttpBinding?使用 REST 入门工具包中的 HttpClient 类,您可以发出标准 HTTP 请求,然后使用 DataContractSerializer 反序列化响应。

例如

var httpClient = new HttpClient();
var content = httpClient.Get("http://example.org/customer/45").Content;
var customer = content.ReadAsDataContract<Customer>()
于 2010-03-25T23:05:52.170 回答
1

我的两分钱是 WCF 擅长使用许多不同的绑定来公开同一个类。与 C# 通信时,请使用擅长异常信息的 SOAP 绑定。如果您必须使用 REST 样式绑定,您可以使用简单的 WebRequest 来调用服务并使用 JSON 序列化程序来反序列化结果。这也将使您可以直接访问响应代码。

于 2010-04-29T16:03:33.973 回答
1

user653761 描述的方法对我有用;访问该HttpWebResponse对象后,我可以DataContractSerializer像这样使用该类:

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

// ...

我想这适用于 WCF 可以序列化的任何东西,如果你使用正确的序列化程序,没有测试性能(还)。

于 2011-09-30T09:39:43.177 回答