我有这三个包装到我的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}" } }