2010-03-25 61 views
8

我有一个.Net WCF客户端使用的REST服务。从WCF获取错误详细信息REST

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

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

但是,我使用了WCF ChannelFactory以及6个相当复杂的接口。这个代理引发的异常总是一个ProtocolException,没有有用的细节。

当我得到这个错误时,有什么办法可以得到响应体吗?


更新

我意识到有不同的方式来做到这一点使用的.Net的负载,并且还有其他的方法来获得错误响应。他们对知道有用,但不回答这个问题。

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

当使用WCF通道时,有什么办法可以获得响应主体的错误HTTP状态吗?

+0

阅读你的解释,听起来你不能控制REST服务本身,这是否正确? – 2010-04-05 14:08:23

+0

其实在这种情况下我们可以,但很难改变。我们的问题是复杂性 - WCF ChannelFactory提供了一种非常好的方式来管理接口。令人讨厌的是,当HTTP头状态为200以外的任何其他东西时,它会抛出响应主体。当我们从REST服务中收到错误时,它会返回一个HTTP 400或500状态,其中包含正文中的详细信息。 – Keith 2010-04-05 22:08:15

回答

1

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

E.g.

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

我喜欢你的简单更好的方法,但我们有大量的接口,几乎所有的方法都需要复杂的POST内容。 ChannelFactory代理实现的代码简单性为我们节省了很多代码复杂度。我知道这可以按照你的方式完成,但是我真正想知道的是:如果我们使用'ChannelFactory'方法,我们可以得到错误细节吗? – Keith 2010-03-26 08:31:15

3

你可以尝试从服务投掷WebProtocolException。这样错误细节应该包含在HTTP响应的主体中。看看这篇文章:

Effective Error Handling with WCF & REST

+0

这正是服务所做的 - 详细信息就像HTTP响应正文中序列化的JSON。问题是ChannelFactory抛出一个异常,除了200以外的任何HTTP头状态没有这些细节。服务工作,这是WCF的客户端实现,这是问题。 – Keith 2010-04-05 14:14:02

1

我的两分钱是WCF善于使用多种不同的绑定暴露同一类。与C#进行通信时,请使用擅长处理异常信息的SOAP绑定。如果您必须使用REST样式绑定,则可以使用简单的WebRequest调用该服务并使用JSON序列化程序对结果进行反序列化。这也可以让你直接访问响应代码。

4

可以检索如下异常详细信息:

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

通过user653761描述的方法对我的作品;其访问HttpWebResponse对象后,我可以使用DataContractSerializer类是这样的:

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

// ... 

我想这会为任何WCF可以序列化,如果你使用正确的序列化,没有测试工作性能(还) 。

3

ProtocolExceptionInnerException将是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();