WCF基本異常處理模式[下篇]_第1頁
WCF基本異常處理模式[下篇]_第2頁
WCF基本異常處理模式[下篇]_第3頁
WCF基本異常處理模式[下篇]_第4頁
WCF基本異常處理模式[下篇]_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

1、WCF基本異常處理模式下篇從FaultContractAttribute的定義我們可以看出,該特性可以在同一個目標對象上面多次應用(AllowMultiple = true)。這也很好理解:對于同一個服務操作,可能具有不同的異常場景,在不同的情況下,需要拋出不同的異常。 1: AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false) 2: public sealed class FaultContractAttribute : Attribute 3: 4: /省略成員 5: 但是,如果你在

2、同一個操作方法上面應用了多了FaultContractAttribute特性的時候,需要遵循一系列的規(guī)則,我們現(xiàn)在就來逐條介紹它們。 一、多次聲明相同的錯誤明細類型比如在下面的代碼中,對于操作Divide,通過FaultContractAttribute特性對同一個錯誤明細類型CalculationError進行了兩次設置。 1: using System.ServiceModel; 2: namespace 3: 4: ServiceContract(Namespace = ) 5: public interface ICalculator 6: 7: OperationContract 8

3、: FaultContract(typeof(CalculationError) 9: FaultContract(typeof(CalculationError) 10: int Divide(int x, int y); 11: 12: WCF服務端框架在初始化ServiceHost,并創(chuàng)建服務表述的時候(關于服務描述,以及在服務寄宿過程中對服務描述的創(chuàng)建,WCF技術(shù)剖析(卷1)的第7章有詳細的介紹),會拋出如圖1所示的InvalidOperationException異常。 圖1 多次聲明相同的錯誤明細類型導致的異常 但是,如果你在應用FaultContractAttribute特性指定

4、相同錯誤明細類型的同時,指定不同的Name或者Namespace,這是允許的。比如下面的代碼中,在兩個FaultContractAttribute特性中,同樣是指定的相同的錯誤明細類型CalculationError,由于我們?yōu)橹付瞬煌腘ame,在寄宿服務的時候?qū)⒉粫猩鲜霎惓5陌l(fā)生。 1: using System.ServiceModel; 2: namespace 3: 4: ServiceContract(Namespace = ) 5: public interface ICalculator 6: 7: OperationContract 8: FaultContract(t

5、ypeof(CalculationError), Name = "CalculationError") 9: FaultContract(typeof(CalculationError), Name = "CalculationException") 10: int Divide(int x, int y); 11: 12: 二、多次聲明不同的具有相同有效名稱錯誤明細類型多次聲明的錯誤類型的類型雖然不同,但是如果我們?yōu)槠渲付ㄏ嗤腘ame和Namespace我們可以將Name和Namespace的組合稱為有效名稱QN:Qualified Name),這依

6、然是不允許的。比如下面的代碼中,通過FaultContractAttribute特性為Divide操作指定了兩個不同的錯誤明細類型(CalculationError和CalculationException),但是設置的名稱卻是相同的(CalculationError)。 1: using System.ServiceModel; 2: namespace 3: 4: ServiceContract(Namespace = ) 5: public interface ICalculator 6: 7: OperationContract 8: FaultContract(typeof(Calc

7、ulationError), 9: Name = "CalculationError", Namespace = ) 10: FaultContract(typeof(CalculationException), 11: Name = "CalculationError", Namespace = ) 12: int Divide(int x, int y); 13: 14: 對于這種情況,在服務寄宿的時候,依然會和上面一樣拋出一個InvalidOperationExcepiton異常,如圖2所示: 圖2 多次申明具有相同有效名稱導致的異常 三、多次聲明

8、不同的具有相同數(shù)據(jù)契約有效名稱的錯誤明細類型 1: using System; 2: using 3: namespace 4: 5: DataContractAttribute(Namespace=) 6: public class CalculationError 7: 8: DataMember 9: public string Operation 10: get; set; 11: DataMember 12: public string Message 13: get; set; 14: 15:  16: DataContractAttribute(Namespace =

9、, Name = "CalculationError") 17: public class CalculationFault 18: 19: DataMember 20: public string Fault 21: get; set; 22: 23: 如果我們通過下面的方式通過FaultContractAttribute特性將這兩個類型應用到同一個服務操作上面,服務寄宿不會出什么問題,客戶端的方法調(diào)用也能正常運行。 1: using System.ServiceModel; 2: namespace 3: 4: ServiceContract(Namespace = )

10、 5: public interface ICalculator 6: 7: OperationContract 8: FaultContract(typeof(CalculationError) 9: FaultContract(typeof(CalculationFault) 10: int Divide(int x, int y); 11: 12: 但是,當我們試圖通過HTTP-GET或者標準的MEX終結(jié)點獲取以WSDL表示的服務元數(shù)據(jù)(Metadata)的時候就會出現(xiàn)問題。至于為什么會導致這樣的問題,你大體可以這樣來理解:當WCF為某個操作的錯誤描述(Fault Description

11、)的時候,會創(chuàng)建一個字典來存儲通過FaultContractAttribute特性指定的基于錯誤明細類型的數(shù)據(jù)契約。對于這個字典來說,它的Key為數(shù)據(jù)契約的有效名稱(QN:Qualified Name),即名稱和命名空間組合。由于CalculationError和CalculationFault具有相同的名稱和命名空間,這無疑會造成Key的沖突。 由于數(shù)據(jù)契約是使對數(shù)據(jù)結(jié)構(gòu)的一種描述,如果兩個數(shù)據(jù)契約時等效的,不管其具體的托管類型是什么,WCF在遇到上述情況的時候,會自動識別并忽略其中一個,從而保證元數(shù)據(jù)能夠正確產(chǎn)生。比如說,如果我們將CalculationFault進行如下的改寫,服務的元數(shù)

12、據(jù)就能夠被正常地獲得了。 1: DataContractAttribute(Namespace = , Name = "CalculationError") 2: public class CalculationFault 3: 4: DataMember(Name = "Operation") 5: public string OperationName 6: get; set; 7: DataMember(Name = "Message") 8: public string Fault 9: get; set; 10: 四、通過X

13、mlSerializer對錯誤明細對象進行序列化對于任何分別是框架來說,序列化和反序列化都是其功能體系中重要的一環(huán)。WCF通過一個重要的對象實現(xiàn)對托管對象的序列化和反序列化:序列化器(Serializer)。具體來說,所有序列化和反序列化的功能又最終落實到兩個具體的序列化器上:DataContractSerializer和XmlSerializer。關于這兩種序列化器,在WCF技術(shù)剖析(卷1)第5章中已經(jīng)有過深入的探討,在這里就需要在畫蛇添足了。 WCF采用的默認序列化器是DataContractSerializer,但是有的時候,我們需要顯示地控制某個服務或者服務的某個操作的序列化行為,通過

14、XmlSerializer來序列化和反序列化操作的參數(shù)對象和返回值。舉個例子,一個服務的絕大部分操作的參數(shù)類型都是通過數(shù)據(jù)契約的方式定義,但是對于個別的操作參數(shù)類型依然沿用的是傳統(tǒng)XML的定義方式。在這種情況下,我們希望的是專門對這幾個操作進行定制,讓它們采用XmlSerializer作為它們的序列化器。 1: AttributeUsage(AttributeTargets.Interface | AttributeTargets.Method | AttributeTargets.Class, Inherited = false, AllowMultiple = false) 2: publ

15、ic sealed class XmlSerializerFormatAttribute : Attribute 3: 4: public XmlSerializerFormatAttribute(); 5: public OperationFormatStyle Style get; set; 6: public bool SupportFaults get; set; 7: public OperationFormatUse Use get; set; 8: 在默認的情況下,XmlSerializerFormatAttribute特性僅僅控制操作的參數(shù)和返回值的序列化行為,而不能控制錯誤明

16、細對象的序列化行為。也就是說,基于在某個操作方法上應用了XmlSerializerFormatAttribute特性,WCF會采用XmlSerializer作為所有參數(shù)和返回值的序列化器,對于出現(xiàn)異常指定的錯誤明細對象,依然采用默認的DataContractSerializer進行序列化和反序列化。我們可以通過SupportFaults屬性來顯式地選擇XmlSerializer作為錯誤明細對象的序列化器。在下面的代碼中,我們將XmlSerializerFormatAttribute特性應用在服務契約的Divide操作上面,并將SupportFaults屬性設為true。 1: using Sy

17、stem.ServiceModel; 2: namespace 3: 4: ServiceContract(Namespace = ) 5: public interface ICalculator 6: 7: OperationContract 8: FaultContract(typeof(CalculationError), Name = "CalculationError") 9: XmlSerializerFormat(SupportFaults = true) 10: int Divide(int x, int y); 11: 12: 那么對于Divide操作,

18、WCF將會采用XmlSerializer同時作為參數(shù)、返回值和錯誤明細對象的序列化器。比如在這個時候,我們采用下面的形式對CalculationError進行重新定義: 1: using System; 2: using 3: using System.Xml; 4: using 5: namespace 6: 7: Serializable 8: public class CalculationError 9: 10: XmlAttributeAttribute("op") 11: public string Operation 12: get; set; 13: XmlElement("Error") 14: public string Message 15: get; set; 16: 17: 在被零除而拋出異常的情況下,WCF將會生成如下一個Fault SOAP,其中s:Body>/ 節(jié)點中的XML為CalculationError對象序列化所的。 1: <s:Envelope xmlns:s x

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論