2010-03-25 62 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();