在閱讀本文前,你應該已經對Sl與WCF的程式設計模型有所了解。當使用WCF與Siverlight進行通信時,一旦服務端處理資料發生了異常,盡管Silverlight用戶端可以使用
AsyncCompletedEventArgs.Error屬性判斷是否發生錯誤,但是由于預設情形下WCF的異常資訊無法傳遞到用戶端,這導緻我們無法準确的判斷錯誤的原因。
圖1
關于這個問題,MSDN上已經對此進行了闡述:在 Silverlight 中建立和處理錯誤 ,這篇文章已經将原了解釋的很清楚了。不過根據MSDN上的步驟,
在Sl應用程式中會遇到一些問題,本篇文章則帶你按步實作Silverlight擷取WCF的錯誤資訊.
1.建立Sl應用程式後,Web項目中添加Siverlight-enabled WCF Service模闆
圖2
2. 添加成功後,會自動為項目添加SilverlightFaultBehavior類,仔細看下SilverlightFaultBehavior類的實作,會發現它将Http的狀态碼改為了200
3.下面進行Web.Config的配置
圖中說明已經很清晰了,一共修改了4個地方,如果你是第一次做,可能每一個地方都要花費不少的時間去了解。如果includeExceptionDetailInFaults沒有進行改動,也可以在服務契約的行為進行設定
[ServiceContract(Namespace = "")]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WcfTestService
{
}
4.現在Web.Config已經配置了,下面在操作契約裡抛出一個異常:
[OperationContract]
public void DoWork()
{
throw new ApplicationException("發生了異常");
}
在浏覽器中可以看到中繼資料後,就可以在用戶端引用服務。
5.調用該操作,可以看到錯誤資訊了:
這篇文章,主要是通過手動配置的方式完成對異常資訊的更改,對初學者麻煩了點.希望給有需要的人一點提示,下一篇将關注WCF的錯誤契約異常處理。
代碼下載下傳:WcfExceptionLesson.rar
對于WCF也學習了一段時間,但是就是一直沒有好好學一下,但是我對它的興趣還是很大的,我覺得這個設計真是太好了,它可以統一 windows下的通信方式,而且僅僅通過改一下配置檔案就可以改變通信方式,它是微軟對SOA的一種架構設計,可以好好學一下。 dotnet3.0是在 dotnet2.0的基礎上加了幾個功能塊,WCF、WF、WPF、CardSpace,對于WCF說起來也很好理它的概念,首先有伺服器端程,再有就是伺服器端程式宿主,最後是用戶端程式。在WCF中,如果沒有指定,服務端的WCF異常不會傳遞到用戶端,如:在等于0時,用戶端根本不知道異常的原因據,也即"Divsionbyzero!"WCF異常資訊不會傳到用戶端。
- [ServiceContract]
- publicclassCalculatorService
- ...{
- [OperationContract]
- intDivide(inta,intb)
- ...{
- if(b==0)thrownewException(“Divisionbyzero!”);
- returna/b;
- }
- }
在最簡單的情況下,我們可以使用空FaultException(它隻包含一個string字元串,稱為錯誤原因),如下所示:
- [ServiceContract]
- publicclassCalculatorService
- ...{
- [OperationContract]
- intDivide(inta,intb)
- ...{
- if(b==0)thrownewFaultException(“Divisionbyzero!”);
- returna/b;
- }
- }
當然,我們可以定義強類型的WCF異常資訊,并在方法上運用FaultContractAttribute來指定它,如下所示:
- [DataContract]
- publicclassMathFault
- ...{
- [DataMember]
- publicstringoperation;
- [DataMember]
- publicstringdescription;
- }
- [ServiceContract]
- publicclassCalculatorService
- ...{
- [FaultContract(typeof(MathFault))]
- [OperationContract]
- intDivide(inta,intb)
- ...{
- if(b==0)
- ...{
- MathFaultm=newMathFault();
- m.operation=”/”;
- m.description=”Divisionbyzero!”;
- thrownewFaultException<MathFault>(m);
- }
- returna/b;
- }
- }
注意:不能用XmlSerializer來序列化Fault相關的對象執行個體,即使在其上使用了XmlSerializerFormatAttribute屬性。