成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

WCF異常處理特點體現

開發 開發工具
WCF異常處理是一個有異于傳統的處理方式。那么它的特殊之處到底在哪里呢?再這里我們將會為大家詳細介紹相關知識。

WCF的出現,為開發人員帶來了不一樣的體驗。在很多方面都有所改變,為編程者提供了一個非常好的開發環境。比如今天為大家介紹的WCF異常處理,就有許多特殊之處,值得我們去深入的研究。

異常消息與特定技術有關,.NET異常同樣如此,因而WCF并不支持傳統的異常處理方式。如果在WCF服務中采用傳統的方式處理異常,由于異常消息不能被序列化,因而客戶端無法收到服務拋出的異常,例如這樣的服務設計:

  1. [ServiceContract(SessionModeSessionMode = SessionMode.Allowed)]  
  2. public interface IDocumentsExplorerService  
  3. {  
  4. [OperationContract]   
  5. DocumentList FetchDocuments(string homeDir);  
  6. }  
  7. [ServiceBehavior(InstanceContextModeInstanceContextMode
    =InstanceContextMode.Single)]  
  8. public class DocumentsExplorerService : 
    IDocumentsExplorerService,IDisposable  
  9. {  
  10. public DocumentList FetchDocuments(string homeDir)  
  11. {  
  12. //Some Codes  
  13. if (Directory.Exists(homeDir))  
  14. {  
  15. //Fetch documents according to homedir  
  16. }  
  17. else  
  18. {  
  19. throw new DirectoryNotFoundException(  
  20. string.Format("Directory {0} is not found.",homeDir));  
  21. }  
  22. }  
  23. public void Dispose()  
  24. {   
  25. Console.WriteLine("The service had been disposed.");  
  26. }  

 

則客戶端在調用如上的服務操作時,如果采用如下的捕獲方式是無法獲取該異常的:

  1. catch (DirectoryNotFoundException ex)  
  2. {  
  3. //handle the exception;  

 

為了彌補這一缺陷,WCF異常處理會將無法識別的異常均當作為FaultException異常對象,因此,客戶端可以捕獲FaultException或者Exception異常:

  1. catch (FaultException ex)  
  2. {  
  3. //handle the exception;  
  4. }  
  5. catch (Exception ex)  
  6. {  
  7. //handle the exception;  

然而,這樣捕獲的異常,卻無法識別DirectoryNotFoundException所傳遞的錯誤信息。尤為嚴重的是這樣的異常處理方式還會導致傳遞消息的通道出現錯誤,當客戶端繼續調用該服務代理對象的服務操作時,會獲得一個CommunicationObjectFaultedException異常,無法繼續使用服務。如果服務被設置為PerSession模式或者Single模式,異常還會導致服務對象被釋放,終止服務。

WCF異常處理專門提供了FaultContract特性,它可以被應用到服務操作上,指明操作可能會拋出的異常類型。例如前面的服務契約就可以修改為:

  1. [ServiceContract(SessionModeSessionMode = SessionMode.Allowed)]  
  2. public interface IDocumentsExplorerService  
  3. {  
  4. [OperationContract]  
  5. [FaultContract(typeof(DirectoryNotFoundException))]  
  6. DocumentList FetchDocuments(string homeDir);  

 

然而,即使通過FaultContract指定了操作要拋出的異常,然而如果服務拋出的異常并非FaultException或者FaultException<T>異常,同樣會導致通道發生錯誤。因此在服務實現中,正確的實現應該如下:

  1. public class DocumentsExplorerService : 
    IDocumentsExplorerService,IDisposable  
  2. {  
  3. public DocumentList FetchDocuments(string homeDir)  
  4. {  
  5. //Some Codes  
  6. if (Directory.Exists(homeDir))  
  7. {  
  8. //Fetch documents according to homedir  
  9. }  
  10. else  
  11. {  
  12. DirectoryNotFoundException exception = 
    new DirectoryNotFoundException();  
  13. throw new FaultException<DirectoryNotFoundException>
    (exception,   
  14. new FaultReason(string.Format("Directory {0} 
    is not found.", homeDir)));  
  15. }  
  16. }  

 

我們可以將服務所要拋出的異常類型作為FaultException<T>的類型參數,然后創建一個FaultReason對象用以傳遞錯誤消息。客戶端在調用服務代理對象時,可以捕獲FaultException< DirectoryNotFoundException>異常,并且該異常不會使得通道發生錯誤,并且客戶端可以繼續使用該服務代理對象。即使服務為PerCall服務,客戶端仍然可以繼續調用服務操作。如果服務為Session服務或Singleton服務,那么即使發生了異常,服務對象也不會被終結。#t#

如果只是為了讓客戶端獲得異常消息,即使不施加FaultContract特性,或者拋出非FaultException異常,我們也可以通過ServiceBehavior特性,將服務的IncludeExceptionDetailInFaults設置為true(默認為false),此時,客戶端可以捕獲拋出的非FaultException異常信息,但該異常仍然會導致通道出現錯誤。

但是,在發布服務與部署服務時,我們應避免將服務的IncludeExceptionDetailInFaults設置為true。

如果不希望使用FaultContract,同時又要保證服務拋出的WCF異常處理能夠被客戶端捕獲,并且不會導致通道錯誤,我們還可以通過錯誤處理擴展的方式實現。此時,我們可以將服務本身作為錯誤處理對象,令其實現System.ServiceModel.Dispatcher.IErrorHandler接口:

  1. public class DocumentsExplorerService : 
    IDocumentsExplorerService,IErrorHandler, IDisposable  
  2. {…} 

 

在該接口的ProvideFault()方法中,可以將非FaultContract異常提升為FaultContract<T>異常,例如將DirectoryNotFoundException異常提升為FaultExceptino<DirectoryNotFoundException>異常:

  1. public void ProvideFault(Exception error,
     MessageVersion version, ref Message fault)  
  2. {  
  3. if (error is DirectoryNotFoundException)  
  4. {  
  5. FaultException<DirectoryNotFoundException> faultException =
     
    new FaultException<DirectoryNotFoundException>(  
  6. new DirectoryNotFoundException(), new FaultReason(error.Message));  
  7. MessageFault messageFault = faultException.CreateMessageFault();  
  8. fault = Message.CreateMessage(version,messageFault,
    faultException.Action);  
  9. }  

 

而在該接口的HandleError()方法中,則可以進行WCF異常處理,例如記錄日志。

要使得錯誤處理擴展生效,還需要向服務通道安裝錯誤處理擴展。方法是讓服務類實現System.ServiceModel.Description.IServiceBehavior接口:

  1. public class DocumentsExplorerService : 
    IDocumentsExplorerService,IErrorHandler,IServiceBehavior,IDisposable  
  2. {…} 

 

然后在ApplyDispatchBehavior()方法中安裝錯誤處理擴展:

  1. public void ApplyDispatchBehavior(ServiceDescription 
    serviceDescription, ServiceHostBase serviceHostBase)  
  2. {  
  3. foreach (ChannelDispatcher dispatcher in serviceHostBase.
    ChannelDispatchers)  
  4. {  
  5. dispatcher.ErrorHandlers.Add(this);  
  6. }  

 

通過這樣的處理,即使服務拋出的異常為DirectoryNotFoundException異常,并且在服務契約中沒有通過FaultContract特性指定該異常,客戶端同樣能夠獲得WCF異常處理的錯誤信息,且該異常不會導致通道發生錯誤,客戶端可以繼續調用服務代理對象的操作。

責任編輯:曹凱 來源: 博客園
相關推薦

2010-02-23 16:15:24

WCF Endpoin

2009-11-05 12:45:25

WCF異常

2009-12-22 16:55:26

WCF性能優勢

2010-02-24 12:41:58

WCF異常處理

2009-12-17 10:29:04

Ruby異常處理結構

2010-02-23 10:57:34

WCF Streami

2009-11-06 15:25:25

WCF異常

2010-02-23 09:34:15

WCF重載

2010-02-25 14:26:48

WCF特點

2010-02-23 09:51:32

WCF MTOM

2009-12-22 16:03:03

WCF異常

2009-12-21 17:40:25

WCF會話

2010-02-22 17:13:40

WCF會話狀態

2010-02-24 14:20:27

WCF并發模型

2010-02-25 17:22:39

WCF服務行為

2009-11-09 10:10:13

WCF異常

2009-12-07 18:38:16

WCF異常

2010-02-22 16:34:17

WCF性能計數器

2010-02-23 13:46:37

WCF數據契約

2010-03-02 18:16:45

WCF可靠性傳輸
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天搞夜夜操 | 亚洲淫视频 | 91久色| 国产不卡一区 | 亚洲国产一区二区三区在线观看 | 在线观看亚洲精品 | 亚洲综合国产 | 国产精品免费看 | www.五月天婷婷 | 综合精品久久久 | 日韩精品免费一区二区在线观看 | 九九免费视频 | 成人一区二区在线 | 18成人在线观看 | 亚洲成人网在线播放 | 成人国产精品免费观看视频 | 国产高清免费视频 | 91精品国产乱码久久久久久久久 | 欧美视频一区二区三区 | 91一区二区三区 | 国产精品成人一区二区三区 | 久久久久9999亚洲精品 | 欧美视频一区 | 久草网在线视频 | 亚洲欧美日韩久久久 | 日韩精品免费在线 | 国产高清在线观看 | 久久久青草婷婷精品综合日韩 | 久久久久久亚洲欧洲 | 欧美日韩精品一区二区三区蜜桃 | 中文字幕在线观看一区 | 日韩中文字幕在线视频观看 | 欧美精品在线一区 | 日韩成人一区 | 999精品在线观看 | 男人亚洲天堂 | 高清黄色毛片 | 精品久久99 | 99re免费 | 久久99久久| 国产午夜精品一区二区三区四区 |