新聞中心
WCF的出現(xiàn),為開發(fā)人員帶來了不一樣的體驗(yàn)。在很多方面都有所改變,為編程者提供了一個(gè)非常好的開發(fā)環(huán)境。比如今天為大家介紹的WCF異常處理,就有許多特殊之處,值得我們?nèi)ド钊氲难芯俊?/p>

為普安等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及普安網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、網(wǎng)站建設(shè)、普安網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
異常消息與特定技術(shù)有關(guān),.NET異常同樣如此,因而WCF并不支持傳統(tǒng)的異常處理方式。如果在WCF服務(wù)中采用傳統(tǒng)的方式處理異常,由于異常消息不能被序列化,因而客戶端無法收到服務(wù)拋出的異常,例如這樣的服務(wù)設(shè)計(jì):
- [ServiceContract(SessionModeSessionMode = SessionMode.Allowed)]
- public interface IDocumentsExplorerService
- {
- [OperationContract]
- DocumentList FetchDocuments(string homeDir);
- }
- [ServiceBehavior(InstanceContextModeInstanceContextMode
=InstanceContextMode.Single)]- public class DocumentsExplorerService :
IDocumentsExplorerService,IDisposable- {
- public DocumentList FetchDocuments(string homeDir)
- {
- //Some Codes
- if (Directory.Exists(homeDir))
- {
- //Fetch documents according to homedir
- }
- else
- {
- throw new DirectoryNotFoundException(
- string.Format("Directory {0} is not found.",homeDir));
- }
- }
- public void Dispose()
- {
- Console.WriteLine("The service had been disposed.");
- }
- }
則客戶端在調(diào)用如上的服務(wù)操作時(shí),如果采用如下的捕獲方式是無法獲取該異常的:
- catch (DirectoryNotFoundException ex)
- {
- //handle the exception;
- }
為了彌補(bǔ)這一缺陷,WCF異常處理會(huì)將無法識(shí)別的異常均當(dāng)作為FaultException異常對(duì)象,因此,客戶端可以捕獲FaultException或者Exception異常:
- catch (FaultException ex)
- {
- //handle the exception;
- }
- catch (Exception ex)
- {
- //handle the exception;
- }
然而,這樣捕獲的異常,卻無法識(shí)別DirectoryNotFoundException所傳遞的錯(cuò)誤信息。尤為嚴(yán)重的是這樣的異常處理方式還會(huì)導(dǎo)致傳遞消息的通道出現(xiàn)錯(cuò)誤,當(dāng)客戶端繼續(xù)調(diào)用該服務(wù)代理對(duì)象的服務(wù)操作時(shí),會(huì)獲得一個(gè)CommunicationObjectFaultedException異常,無法繼續(xù)使用服務(wù)。如果服務(wù)被設(shè)置為PerSession模式或者Single模式,異常還會(huì)導(dǎo)致服務(wù)對(duì)象被釋放,終止服務(wù)。
WCF異常處理專門提供了FaultContract特性,它可以被應(yīng)用到服務(wù)操作上,指明操作可能會(huì)拋出的異常類型。例如前面的服務(wù)契約就可以修改為:
- [ServiceContract(SessionModeSessionMode = SessionMode.Allowed)]
- public interface IDocumentsExplorerService
- {
- [OperationContract]
- [FaultContract(typeof(DirectoryNotFoundException))]
- DocumentList FetchDocuments(string homeDir);
- }
然而,即使通過FaultContract指定了操作要拋出的異常,然而如果服務(wù)拋出的異常并非FaultException或者FaultException
- public class DocumentsExplorerService :
IDocumentsExplorerService,IDisposable- {
- public DocumentList FetchDocuments(string homeDir)
- {
- //Some Codes
- if (Directory.Exists(homeDir))
- {
- //Fetch documents according to homedir
- }
- else
- {
- DirectoryNotFoundException exception =
new DirectoryNotFoundException();- throw new FaultException
(exception,- new FaultReason(string.Format("Directory {0}
is not found.", homeDir)));- }
- }
- }
我們可以將服務(wù)所要拋出的異常類型作為FaultException
如果只是為了讓客戶端獲得異常消息,即使不施加FaultContract特性,或者拋出非FaultException異常,我們也可以通過ServiceBehavior特性,將服務(wù)的IncludeExceptionDetailInFaults設(shè)置為true(默認(rèn)為false),此時(shí),客戶端可以捕獲拋出的非FaultException異常信息,但該異常仍然會(huì)導(dǎo)致通道出現(xiàn)錯(cuò)誤。
但是,在發(fā)布服務(wù)與部署服務(wù)時(shí),我們應(yīng)避免將服務(wù)的IncludeExceptionDetailInFaults設(shè)置為true。
如果不希望使用FaultContract,同時(shí)又要保證服務(wù)拋出的WCF異常處理能夠被客戶端捕獲,并且不會(huì)導(dǎo)致通道錯(cuò)誤,我們還可以通過錯(cuò)誤處理擴(kuò)展的方式實(shí)現(xiàn)。此時(shí),我們可以將服務(wù)本身作為錯(cuò)誤處理對(duì)象,令其實(shí)現(xiàn)System.ServiceModel.Dispatcher.IErrorHandler接口:
- public class DocumentsExplorerService :
IDocumentsExplorerService,IErrorHandler, IDisposable- {…}
在該接口的ProvideFault()方法中,可以將非FaultContract異常提升為FaultContract
- public void ProvideFault(Exception error,
MessageVersion version, ref Message fault)- {
- if (error is DirectoryNotFoundException)
- {
- FaultException
faultException =
new FaultException( - new DirectoryNotFoundException(), new FaultReason(error.Message));
- MessageFault messageFault = faultException.CreateMessageFault();
- fault = Message.CreateMessage(version,messageFault,
faultException.Action);- }
- }
而在該接口的HandleError()方法中,則可以進(jìn)行WCF異常處理,例如記錄日志。
要使得錯(cuò)誤處理擴(kuò)展生效,還需要向服務(wù)通道安裝錯(cuò)誤處理擴(kuò)展。方法是讓服務(wù)類實(shí)現(xiàn)System.ServiceModel.Description.IServiceBehavior接口:
- public class DocumentsExplorerService :
IDocumentsExplorerService,IErrorHandler,IServiceBehavior,IDisposable- {…}
然后在ApplyDispatchBehavior()方法中安裝錯(cuò)誤處理擴(kuò)展:
- public void ApplyDispatchBehavior(ServiceDescription
serviceDescription, ServiceHostBase serviceHostBase)- {
- foreach (ChannelDispatcher dispatcher in serviceHostBase.
ChannelDispatchers)- {
- dispatcher.ErrorHandlers.Add(this);
- }
- }
通過這樣的處理,即使服務(wù)拋出的異常為DirectoryNotFoundException異常,并且在服務(wù)契約中沒有通過FaultContract特性指定該異常,客戶端同樣能夠獲得WCF異常處理的錯(cuò)誤信息,且該異常不會(huì)導(dǎo)致通道發(fā)生錯(cuò)誤,客戶端可以繼續(xù)調(diào)用服務(wù)代理對(duì)象的操作。
本文標(biāo)題:WCF異常處理特點(diǎn)體現(xiàn)
標(biāo)題網(wǎng)址:http://www.fisionsoft.com.cn/article/djejdgd.html


咨詢
建站咨詢
