2013-05-08 26 views
0

我有這三個包裝到我的WCF服務項目:使用Enterpise庫6使用WCF的異常處理應用程序塊?

EnterpriseLibrary.Common Version 6.0.1304.0
EnterpriseLibrary.ExceptionHandling 6.0.1304.0
EnterpriseLibrary.ExceptionHandling.WCF Version 6.0.1304.0

這裏的服務接口和MyTestFault DataContract:

[ServiceContract] 
public interface IRepairService 
{ 
    [OperationContract] 
    [FaultContract(typeof(MyTestFault))] 
    string SaveRepairCode(string failureCode, string description); 
} 

[DataContract] 
public class MyTestFault 
{ 
    #region Member Fields 

    private string _message = "An unexpected error occured while executing the service method."; 

    #endregion 

    #region Properties 

    [DataMember] 
    public string Message 
    { 
     get { return _message; } 
     set { _message = value; } 
    } 

    #endregion 

    #region Constructor(s) 

    public MyTestFault() { } 

    #endregion 
} 

這裏是服務的實現:

[ExceptionShielding("TestPolicy")] 
public class RepairService : IRepairService 
{ 
    #region Private members 

    private WimDAL wimDAL; 
    ExceptionManager exManager; 

    #endregion 

    #region Constructor(s) 

    public RepairService() 
    { 
     wimDAL = new WimDAL(); 

     var testPolicy = new List<ExceptionPolicyEntry> 
     { 
      { 
       new ExceptionPolicyEntry(
        typeof(SqlException), 
        PostHandlingAction.ThrowNewException, 
        new IExceptionHandler[] 
        { 
         new FaultContractExceptionHandler(
          typeof(MyTestFault), 
          "SqlException Occurred.", 
          new NameValueCollection(){ { "Message", "Message" }}) 
        }) 
      }, 
      { 
       new ExceptionPolicyEntry(
        typeof(Exception), 
        PostHandlingAction.ThrowNewException, 
        new IExceptionHandler[] 
        { 
         new FaultContractExceptionHandler(
          typeof(MyTestFault), 
          "Exception Occurred.", 
          new NameValueCollection(){ { "Message", "Message" }}) 
        }) 
      } 
     }; 

     var policies = new List<ExceptionPolicyDefinition>(); 
     policies.Add(new ExceptionPolicyDefinition(
      "TestPolicy", testPolicy)); 

     exManager = new ExceptionManager(policies); 
    } 

    #endregion 

    /// <summary> 
    /// Insert a new fail code with description into RPCODE. 
    /// Duplicate primary key will throw SqlException that should be processed by EHAB 
    /// </summary> 
    public string SaveRepairCode(string failureCode, string description) 
    { 
     using (TransactionScope txScope = new TransactionScope()) 
     { 
      WimSQLCommand sc = new WimSQLCommand() { StoredProcedure = "Repair.RPCODE_Insert" }; 

      sc.Parameters.Add(new SqlParameter("@FailureCode", failureCode)); 
      sc.Parameters.Add(new SqlParameter("@Desc", description)); 

      exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy"); 

      txScope.Complete(); 
      return "<Save_Repair_Code></Save_Repair_Code>"; 
     } 
    } 
} 

現在,我有一個TestClient控制檯應用程序,它是同一個項目的一部分,它具有對項目和服務參考的引用。從那裏,我所說的SaveRepairCode()方法,並試圖抓住的具體故障異常,像這樣:

ServiceReference1.RepairServiceClient r = new ServiceReference1.RepairServiceClient(); 

Console.WriteLine("Enter a new repair code:"); 
string repairCode = Console.ReadLine(); 
Console.WriteLine("Enter description:"); 
string description = Console.ReadLine(); 

try 
{ 
    r.SaveRepairCode(repairCode, description); 
} 
catch (FaultException<MyTestFault> ex) 
{ 
    //do something 
    throw; 
} 
catch (FaultException fex) 
{ 
    //do something 
    throw; 
} 

最後,我運行控制檯應用程序,並嘗試保存重複修復代碼。我通過調試知道這會導致發生SqlException。在我遍歷SqlException之後,我看到「FaultContractWrapperException未被用戶代碼處理」異常,並且它具有我在「發生SqlException」策略中指定的消息。當我跨過那我回去給客戶端,看到此錯誤:

是的CommunicationException未處理
服務器未提供有意義的回覆;這可能是由於合同不匹配,會話過早關閉或內部服務器錯誤造成的。

PS - 這是企業庫6與WCF和我沒有手動更改到web.config ...是的,includeExceptionDetailInFaults設置爲false。

我在這裏錯過了什麼?提前致謝。


UPDATE
看起來像我實例化新ExceptionManager後失蹤的這一行代碼。

ExceptionPolicy.SetExceptionManager(exManager); 

很高興地看到,這一行代碼是沒有在企業庫6 - 四月2013.chm但它的「開發人員指南,以微軟企業庫,Preview.pdf」中的269第90頁上在包含那一行後,我進入客戶端的正確的FaultException catch。

這樣說,我仍然無法在客戶端上獲得其他MyTestFault屬性。例如,如果我將公共字符串StoredProcedureName添加到MyTestFault並將其映射到SqlException的「Procedure」屬性,我總是在客戶端上看到空。該政策在這個唯一的變化是添加像這樣的映射:

new NameValueCollection(){ { "Message", "{Message}" }, { "StoredProcedureName", "{Procedure}" } } 

回答

0

事實證明,這條線是罪魁禍首。

exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy"); 

使用ExceptionManager的Process方法的缺省情況下,只需執行命令您期望一個潛在的例外像這樣。

wimDAL.Execute_NonQueryNoReturn(sc); 

這不符合「Microsoft企業圖書館預覽開發人員指南」。pdf「說,但我猜文檔仍然是一個工作正在進行中,我希望這可以幫助別人。

相關問題