我有這三個包裝到我的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}" } }