2010-03-07 88 views
1

在我的Silverlight應用程序中,我使用Visual Studio生成的客戶端(添加服務引用...)異步調用Web服務。
我的代碼如下所示:Silverlight和WCF:處理'WCF down'異常/ WCF連接檢查

ServiceClient serviceClient = new ServiceClient(); 
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted); 
serviceClient.GetServerTimeAsync(); 

void serviceClient_GetServerTimeCompleted(object sender, GetServerTimeCompletedEventArgs e) 
{ 
     // do nothing atm 
} 

一切工作正常,只要該服務啓動並運行,但是當服務沒有運行,我得到:

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) 

「在 操作期間發生異常,導致結果無效。 檢查InnerException以獲取異常 的詳細信息。「

的InnerException

「發生錯誤,而試圖 做出請求URI 的‘http://’,這可能是 由於試圖在一個交叉訪問服務 沒有適當的 跨域策略或者 策略不適用於SOAP 服務您可能需要聯繫 服務的所有者以發佈 跨域策略文件,它允許發送與SOAP相關的HTTP標頭 。通過使用Web 服務代理中的內部類型,而不使用 InternalsVisibleToAttribute屬性,也可能導致此錯誤 。 請參閱內部異常 更多的細節。」

這是有道理的,我在這種情況下得到一個例外,但我無法弄清楚是怎麼趕上我的客戶端代碼中的異常。是有一個標準的方法來做到這一點?如果我理解這是如何工作的,當我的代碼調用生成的代碼時,它會產生另一個線程,它實際調用Web服務並等待響應。該線程和生成的異常代碼我的呼叫代碼(見上)或我的回撥方式都沒有機會看到異常情況

謝謝

Christian

回答

1

有很多原因不使用Visual Studio中的「添加服務引用」功能。這裏有一篇關於這個問題的好文章(和長篇),以及how to use WCF creating your clients。我現在正在自己解決這些問題。

有關「添加服務引用」的問題包括可下載客戶端.XAP文件中的代碼膨脹,難以維護生成的代碼,當服務器地址和端口在客戶端配置中被硬編碼時難以進行登臺或發送代碼文件(也嵌入在.XAP中)等等。構建您自己的客戶端還將使您更好地管理客戶端代碼中的異常。

有一些權衡;您需要將數據合同類移植到Silverlight環境。 (你不能只添加一個引用到服務器端的.NET程序集,它不起作用。)上面鏈接的網站在re-using assemblies in Silverlight上有一篇很好的文章,但處理這個問題最簡單的方法是從您的Silverlight項目中添加指向服務器端類的鏈接。 (在Silverlight項目中,右鍵單擊並添加 - >添加現有項目...並找到要包含的項目,但不單擊添加按鈕,單擊其旁邊的向下箭頭並單擊「添加爲鏈接「)。注意其他引用和使用引用服務器端類的語句;您可能需要進行條件編譯,以便您的數據合同類在客戶端項目中乾淨地編譯。

總的來說,它確實看起來像一個更清潔的方式,尤其是對於可能使用大量服務合同和數據合同的大型項目,或者需要將Silverlight項目作爲商業應用程序的一部分運輸人們的服務器。對於可測試性來說,它也應該更加清潔,特別是對於集成和分期測試。

+0

感謝,我將深入探討這些網頁,但我不想改變我交談的WCF的方式。使用添加服務引用非常「方便」,我沒有時間atm .. – 2010-03-09 05:07:30

0

我以前遇到過這個問題 - 您需要在您的ServiceClient設置代碼中添加異常處理代碼。我通常檢查以下的CommunicationExceptionTimeoutException異常,並EndpointNotFoundException,並告訴他們的東西被破壞用戶提供適當的對話框:

ServiceClient serviceClient; 
try 
{ 
    serviceClient = new ServiceClient(); 
    serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted); 
    serviceClient.GetServerTimeAsync(); 
} 
catch (EndpointNotFoundException ex) 
{ 
    // log exception 
    // show error dialog 
} 

注:這不會處理asnchronous期間遇到的錯誤方法回調 - 它需要它自己的(類似的)異常處理。

+0

Bermo,你有一個示例顯示瞭如何包裝ServiceClient安裝程序代碼?我的意思是,你使用服務參考? 謝謝 基督徒 – 2010-03-09 05:08:29

+0

更新後添加一些示例代碼。 – Bermo 2010-03-09 07:09:48

0

其實你必須把crossdomainaccesspolicy.xml放在IIS默認的網站根目錄下。 您複製下面給出的xml內容並保存在ClinetAccespolicy.xml的名稱中,然後放在IIS默認網站根文件夾中。