《WCF技术内幕》翻译25:第2部分_第5章_消息:创建一个消息(下)之MessageFault
生活随笔
收集整理的這篇文章主要介紹了
《WCF技术内幕》翻译25:第2部分_第5章_消息:创建一个消息(下)之MessageFault
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Message和SOAP Fault老徐備注1
Message類型定義了一些用來創(chuàng)建表示SOAP Fault消息對(duì)象的工廠方法。SOAP Fault是SOAP消息的一種形式,它用來表示錯(cuò)誤信息。在SOAP規(guī)范(1.1 和1.2)對(duì)于消息體內(nèi)容,并且某些時(shí)候,關(guān)于SOAP消息頭塊的規(guī)定都存在差別。Message是對(duì)于SOAP消息的CLR抽象,Message可以表示SOAP Fault,和表示一個(gè)SOAP消息一樣。本節(jié)會(huì)描述一些SOAP Fault的基本概念和創(chuàng)建表示SOAP Fault消息的基本類型以及如何創(chuàng)建一個(gè)表示SOAP Fault的Message實(shí)例。SOAP Fault 剖析
SOAP Fault遵守SOAP規(guī)范(1.1 和1.2)。根本上,SOAP1.1 Fault包含一個(gè)SOAP body,body里包裝了一個(gè)必須的faultcode老徐備注2、faultstring元素,還有一個(gè)可選的faultactor和faultdetail元素。為了避免重復(fù)敘述這些規(guī)范,你可以在這里http://www.w3.org/TR/soap11找到更多的可選擇元素的消息規(guī)范。在更高層次上,faultcode表示一個(gè)標(biāo)識(shí)符,接受者和發(fā)送者可以用來辨別錯(cuò)誤SOAP1.1規(guī)范,定義了一個(gè)faultcode的小集合,但是程序可以定義自己使用的唯一的faultcode。Faultstring表示一種人工可讀的faultcode,它不是要給接收程序(除非你想吧Faultstring顯示給用戶)。Faultcode是一個(gè)描述錯(cuò)誤來源的URI。 SOAP Fault 從SOAP 1.1到SOAP 1.2發(fā)生了很大的變化。因?yàn)镾OAP 1.2是建立在Infoset上的, SOAP 1.2 Fault本質(zhì)上是由一個(gè)信息條目集合組成。除了這些變化,SOAP Fault組成部分的名字也做了修改和擴(kuò)展,以包含更多的描述信息。SOAP 1.2規(guī)定SOAP Fault應(yīng)該包含一個(gè)必須的Code和Reason(原因),一個(gè)可選的Node、Role或Detail(詳細(xì)信息)。何時(shí)增加這些信息的詳細(xì)規(guī)定可以在這里查看:http://www.w3.org/TR/soap12-part1/#soapfault。通常來說,Code是發(fā)生錯(cuò)誤的標(biāo)識(shí)符,而且也允許使用子code表示更細(xì)粒度的信息。SOAP 1.2定義了一些Code,并且允許程序定義自己的Code。Reason便是人工可讀的錯(cuò)誤解釋信息。Node表示產(chǎn)生錯(cuò)誤的消息參與者。Role信息表示的是SOAP錯(cuò)誤產(chǎn)生時(shí),消息參與者的角色。Detail是給其它消息參與者準(zhǔn)備的錯(cuò)誤信息。 SOAP 1.1 和1.2 Fault,拋去他們的區(qū)別,在他們描述的信息類型上還是很相似的。兩者都規(guī)定了錯(cuò)誤代碼的標(biāo)簽,人工可讀的錯(cuò)誤描述信息,導(dǎo)致SOAP Fault的消息參與者信息和錯(cuò)誤的其它信息。為這目的,WCF定義了一個(gè)表示SOAP 1.1和SOAP 1.2 FaultSystem.ServiceModel.Channels.MessageFault類型。在我們學(xué)習(xí)如何表示SOAP 1.1 和SOAP 1.2描述的SOAP Fault之前,我們先來看看MessageFault類型如何概括歸納SOAP Fault的。MessageFault
The MessageFault type is a way to describe error information in a SOAP-version-agnostic manner. Keeping in mind that WCF has a highly layered architecture, the MessageFault type provides tremendous flexibility when processing SOAP messages and optionally generating exceptions. MessageFault類型可以描述各種SOAP版本的錯(cuò)誤信息。記住WCF擁有更高層的架構(gòu),MessageFault類型在處理SOAP消息或者產(chǎn)生異常的時(shí)候提供了巨大的靈活性。 創(chuàng)建一個(gè) MessageFault對(duì)象 ?像許多WCF里的別的類型一樣,MessageFault是個(gè)定義了幾個(gè)工廠方法的抽象類型。這些工廠方法接受表示SOAP Fault里存儲(chǔ)信息的參數(shù)。此外MessageFault同樣定義了接受產(chǎn)生SOAP Fault的消息參與者的標(biāo)識(shí)作為參數(shù)。值得注意的是,MessageFault定義了一個(gè)工廠方法接受一個(gè)Message作為參數(shù)。這個(gè)方法在WCF接收一個(gè)SOAP FaultMessage,并需要傳遞這個(gè)錯(cuò)誤信息到別的WCF基礎(chǔ)結(jié)構(gòu)部分進(jìn)行處理的時(shí)候,非常有用。 System.ServiceModel.FaultCode類型表示faultcode信息。這個(gè)類型定義了幾個(gè)工廠方法作為構(gòu)造函數(shù)。所有的構(gòu)建方法云系使用子code。FaultCode類型上的工廠方法,會(huì)自動(dòng)產(chǎn)生發(fā)送者和接收者的錯(cuò)誤代碼(像SOAP 1.1 和SOAP 1.2定義的一樣)。 System.ServiceModel.FaultReason類型表示faultreason。最簡單的情況,一個(gè)構(gòu)造函數(shù)接受一個(gè)String字符串作為參數(shù)。String表示人工可讀的錯(cuò)誤信息。因?yàn)槿苏f的語言不同(Microsoft .NET開發(fā)人員也不會(huì)說一個(gè)語言),FaultReason類型定義了構(gòu)造函數(shù)和方法允許程序嵌入多種版本的String和適當(dāng)?shù)幕诓煌幕拿枋鲂畔ⅰ?除了那一個(gè)MessageFault定義的工廠方法,其它的都接受一個(gè)FaultCode 和FaultReason類型作為參數(shù)。因此,這些類型必須在MessageFault創(chuàng)建之前實(shí)例化,除了從Message創(chuàng)建MessageFault。幾個(gè)工廠方法也接受Object作為參數(shù),這個(gè)表示額外的錯(cuò)誤信息。對(duì)于Message工廠方法里的Object參數(shù),它們必須支持序列化(更多序列化的內(nèi)容在第9章)。這個(gè)參數(shù)的存在帶來一個(gè)問題,”我該使用什么類型作為參數(shù)?”因?yàn)镾ystem.Exception 是可序列化的,你或許會(huì)傳遞一個(gè)Exception參數(shù)。我強(qiáng)烈建議你打消這個(gè)想法。我更愿意自定義一個(gè)傳遞錯(cuò)誤信息給其它消息參與者的類型。正如我們將會(huì)在第9章看到的一樣,這給契約帶來了一個(gè)變化。 從MessageFault??創(chuàng)建Message?? 我們一旦創(chuàng)建了MessageFault,我們可以調(diào)用Message上定義的別的工廠方法來創(chuàng)建一個(gè)Message。下面的代碼演示了如何使用FaultCode、FaultReason和Object去創(chuàng)建一個(gè)MessageFault,也包括如何從MessageFault創(chuàng)建一個(gè)Message。static void Main() {// create a Receiver Fault Code
FaultCode faultCode = FaultCode.CreateReceiverFaultCode("MyFaultCode",
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"urn:MyNS");
// create a meaningful FaultReason
FaultReason faultReason = new FaultReason("The value must be > 10");
????
// create an object that represents the SOAP Fault detail
SomeFaultDetail faultDetail = new SomeFaultDetail("Contoso", "SomeApp");
????
// create a MessageFault
MessageFault messageFault = MessageFault.CreateFault(faultCode,
???????????????????????????????????????????????????????????????????????????????????????????????????????????? faultReason,
???????????????????????????????????????????????????????????????????????????????????????????????????????????? faultDetail);
????
// Build a Message from the MessageFault, passing the MessageVersion
CreateAndShowMessage(messageFault, MessageVersion.Soap11WSAddressing10);
CreateAndShowMessage(messageFault, MessageVersion.Soap12WSAddressing10);
}
????
private static void CreateAndShowMessage(MessageFault messageFault,
???????????????????????????????????????????????????????????????????????????????? MessageVersion version) {
// actually create the Message object w/version info
Message message = Message.CreateMessage(version,
????????????????????????????????????????????????????????????messageFault,
????????????????????????????????????????????????????????????????????????????????????"urn:SomeFaultAction");
// show the contents of the Message
Console.WriteLine("{0}\n", message.ToString());
}
????
// a serializable type for storing Fault detail information
[Serializable]
sealed class SomeFaultDetail {
String companyName;
String applicationName;
DateTime? dateOccurred;
????
internal SomeFaultDetail(String companyName, String applicationName) {
????????this.companyName = companyName;
????????this.applicationName = applicationName;
????????//this.dateOccurred = null;
????????this.dateOccurred = DateTime.Now;
}
} 運(yùn)行代碼,產(chǎn)生以下結(jié)果:<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
????????xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
????????<a:Action s:mustUnderstand="1">
????????????urn:SomeFaultAction
????????</a:Action>
</s:Header>
<s:Body>
????????<s:Fault>
????????????<faultcode xmlns:a="urn:MyNS">a:MyFaultCode</faultcode>
????????????<faultstring xml:lang="en-US">The value must be > 10</faultstring>
????????????<detail>
????????????????<Program.SomeFaultDetail xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/MessageFaults">
????????????????????<applicationName>SomeApp</applicationName>
????????????????????<companyName>Contoso</companyName>
????????????????????<dateOccurred>2006-06-14T12:34:44.52325-04:00</dateOccurred>
????????????????</Program.SomeFaultDetail>
????????????</detail>
????????</s:Fault>
</s:Body>
</s:Envelope>
????
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing"
????????xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
????????<a:Action s:mustUnderstand="1">
????????????urn:SomeFaultAction
????????</a:Action>
</s:Header>
<s:Body>
????????<s:Fault>
????????????<s:Code>
????????????????<s:Value>s:Receiver</s:Value>
????????????????<s:Subcode>
????????????????????<s:Value xmlns:a="urn:MyNS">a:MyFaultCode</s:Value>
????????????????</s:Subcode>
????????????</s:Code>
????????????<s:Reason>
????????????????<s:Text xml:lang="en-US">The value must be > 10</s:Text>
????????????</s:Reason>
????????????<s:Detail>
????????????????<Program.SomeFaultDetail xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/MessageFaults">
????????????????????<applicationName>SomeApp</applicationName>
????????????????????<companyName>Contoso</companyName>
????????????????????<dateOccurred>2006-06-14T12:34:44.52325-04:00</dateOccurred>
????????????????</Program.SomeFaultDetail>
????????????</s:Detail>
????????</s:Fault>
</s:Body>
</s:Envelope> 這段代碼展示的最顯著的特性就是MessageFault如何做到消息版本獨(dú)立。第一次調(diào)用CreateAndShowMessage傳遞的參數(shù)是MessageFault和 MessageVersion.Soap11WSAddressing10,結(jié)果是一個(gè)SOAP 1.1 Fault。第2次調(diào)用CreateAndShowMessage傳遞的參數(shù)是同一個(gè)MessageFault,但是MessageVersion變?yōu)镸essageVersion.Soap12WSAddressing10。結(jié)果就是一個(gè)SOAP 1.2 Fault。 前面代碼展示了如何從MessageFault創(chuàng)建一個(gè)Message。Message定義了一個(gè)接受一個(gè)MessageFault參數(shù)工廠方法和幾個(gè)接受一個(gè)FaultCode的工廠方法。Message的這些工廠方法允許程序創(chuàng)建一個(gè)MessageFault或FaultCode標(biāo)志錯(cuò)誤。然后傳遞這個(gè)對(duì)象給WCF基礎(chǔ)結(jié)構(gòu)里的其它層去產(chǎn)生一個(gè)Message對(duì)象。 注釋:這看起來像個(gè)小功能,但是確帶來了巨大好處。作用上,MessageFault?類型的MessageVersion版本兼容能力允許在WCF基礎(chǔ)結(jié)構(gòu)的另外部分來決定SOAP消息版本。換句話說,WCF基礎(chǔ)結(jié)構(gòu)里只有一層為了傳輸需要知道SOAP消息版本,因此創(chuàng)建了一個(gè)熱拔插和可擴(kuò)展的框架。
老徐備注
1.SOAP Fault 元素 來自 SOAP 消息的錯(cuò)誤消息被攜帶于 Fault 元素內(nèi)部。 如果已提供了 Fault 元素,則它必須是 Body 元素的子元素。在一條 SOAP 消息中,Fault 元素只能出現(xiàn)一次。 SOAP 的 Fault 元素用于下列子元素:| 子元素 | 描述 |
| <faultcode> | 供識(shí)別故障的代碼 |
| <faultstring> | 可供人閱讀的有關(guān)故障的說明 |
| <faultactor> | 有關(guān)是誰引發(fā)故障的信息 |
| <detail> | 存留涉及 Body 元素的應(yīng)用程序?qū)S缅e(cuò)誤信息 |
| 錯(cuò)誤 | 描述 |
| VersionMismatch | SOAP Envelope 元素的無效命名空間被發(fā)現(xiàn) |
| MustUnderstand | Header 元素的一個(gè)直接子元素(帶有設(shè)置為 "1" 的 mustUnderstand 屬性)無法被理解。 |
| Client | 消息被不正確地構(gòu)成,或包含了不正確的信息。 |
| Server | 服務(wù)器有問題,因此無法處理進(jìn)行下去。 |
總結(jié)
以上是生活随笔為你收集整理的《WCF技术内幕》翻译25:第2部分_第5章_消息:创建一个消息(下)之MessageFault的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 2042:不容易系列之二
- 下一篇: lammps教程:NEMD方法计算热导率