2013-05-08 77 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“说,但我猜文档仍然是一个工作正在进行中,我希望这可以帮助别人。

相关问题