![](/img/trans.png)
[英]Configuring Fault Contract Exception Handlers in Enterprise Library 6 for WCF
[英]Enterprise Library Exception Handling for WCF Fault Contracts - CLIENT SIDE
我有一個與WCF服務通信的Windows服務。 WCF服務均受故障保護,並生成自定義UserFaultContracts和ServiceFaultContracts。 那里沒有問題。
在Windows服務中,我使用EntLib進行異常處理和日志記錄。
我不想嘗試發現錯誤
try
{
}
catch (FaultException<UserFaultContract>)
{
}
我想使用EntLib
try
{
}
catch (Exception ex)
{
var rethrow = ExceptionPolicy.HandleException(ex, "Transaction Policy");
if (rethrow) throw;
}
但是,這在我的事務處理策略中也有效,我想記錄UserFaultContract的詳細信息。 這是我脫膠的地方。 我討厭脫膠。 故障被捕獲並記錄下來...但是我無法獲得故障的詳細信息。
我的例外政策是
<add name="Transaction Policy">
<exceptionTypes>
<add type="System.Exception, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="None" name="Exception">
<exceptionHandlers>
<add logCategory="General" eventId="200" severity="Error" title="Transaction Error"
formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
priority="2" useDefaultLogger="true" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Logging Handler" />
</exceptionHandlers>
</add>
<add type="System.ServiceModel.FaultException, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="None" name="FaultException">
<exceptionHandlers>
<add logCategory="General" eventId="200" severity="Error" title="Service Fault"
formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
priority="2" useDefaultLogger="true" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Logging Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
記錄的異常為:
時間戳記:5/13/2010 14:53:40消息:HandlingInstanceID:e9038634-e16e-4d87-ab1e-92379431838b
2010年5月13日10:53:40類型:System.ServiceModel.FaultException`1 [[LCI.DispatchMaster.FaultContracts.ServiceFaultContract,LCI.DispatchMaster.FaultContracts,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]] ,System.ServiceModel,版本= 3.0.0.0,區域性=中性,PublicKeyToken = b77a5c561934e089消息:DispatchMaster服務出現內部錯誤。 源:mscorlib幫助鏈接:詳細信息:LCI.DispatchMaster.FaultContracts.ServiceFaultContract操作: http : //LCI.DispatchMaster.LogicalChoices.com/ITruckMasterService/MergeScenarioServiceFaultContractFault代碼:System.ServiceModel.FaultCode原因:DispatchMaster服務存在內部故障。 數據:System.Collections.ListDictionaryInternal TargetSite:無效HandleReturnMessage(System.Runtime.Remoting.Messaging.IMessage,System.Runtime.Remoting.Messaging.IMessage)堆棧跟蹤:
在故障聯系人中,有一個ID和一條消息。 如您所見,我希望EntLib記錄ID和消息。
我假設我將不得不編寫一個自定義處理程序來吸引故障詳細信息,但是我想問一下是否在EntLib中缺少某些內容,這可能有助於我避免執行該任務。
感謝任何願意提供幫助的人。
如果確定WCF服務中的所有配置均正確,則應該能夠獲得在服務端填充的消息。
以下代碼應在客戶端顯示完整的異常詳細信息。
private void CalculateDivision(decimal numerator, decimal denominator)
{
try
{
// Create an instance of service client.
ICalculatorService svc = new CalculatorServiceClient();
// Call service method.
Console.WriteLine("Result is: {0}", svc.Divide(numerator, denominator));
}
catch (Exception ex)
{
// Show details of the exception returned to the calling code.
ShowExceptionDetails(ex);
// Show details of the fault contract returned from the WCF service.
ShowFaultContract(ex);
}
}
public void ShowExceptionDetails(Exception ex)
{
Console.WriteLine("Exception type {0} was thrown.", ex.GetType().ToString());
Console.WriteLine("Message: '{0}'", ex.Message);
Console.WriteLine("Source: '{0}'", ex.Source);
if (null == ex.InnerException)
{
Console.WriteLine("No Inner Exception");
}
else
{
Console.WriteLine();
Console.WriteLine("Inner Exception: {0}", ex.InnerException.ToString());
}
Console.WriteLine();
}
private static void ShowFaultContract(Exception ex)
{
var faultContract = ex as FaultException<CalculatorFault>;
if (faultContract != null)
{
CalculatorFault calculatorFault = faultContract.Detail;
Console.WriteLine("Fault contract detail: ");
Console.WriteLine("Fault ID: {0}", calculatorFault.FaultID);
Console.WriteLine("Message: {0}", calculatorFault.FaultMessage);
}
}
如果仍然無法正常工作,則肯定是服務端出了問題。 讓我們看看上面定義的特定客戶端的服務代碼應該是什么樣的。
[ServiceContract]
public interface ICalculatorService
{
[OperationContract]
[FaultContract(typeof(CalculatorFault))]
decimal Divide(decimal num1, decimal num2);
}
[DataContract]
public class CalculatorFault
{
[DataMember]
public Guid FaultID { get; set; }
[DataMember]
public string FaultMessage { get; set; }
}
[ExceptionShielding("CalculatorServicePolicy")]
public class CalculatorService : ICalculatorService
{
public decimal Divide(decimal num1, decimal num2)
{
Calculator calc = new Calculator();
return calc.Divide(num1, num2);
}
}
//Call the following function in Application_Start function of your Global.asax file
private void ConfigureExceptionHandlingBlock()
{
var policies = new List<ExceptionPolicyDefinition>();
var mappings = new NameValueCollection();
mappings.Add("FaultID", "{Guid}");
mappings.Add("FaultMessage", "{Message}");
var calculatorServicePolicy = new List<ExceptionPolicyEntry>
{
new ExceptionPolicyEntry(typeof(Exception),
PostHandlingAction.ThrowNewException,
new IExceptionHandler[]
{
new FaultContractExceptionHandler(typeof(CalculatorFault), "Some internal service Error. Check service logs.", mappings)
})
};
policies.Add(new ExceptionPolicyDefinition("CalculatorServicePolicy", calculatorServicePolicy));
ExceptionManager exManager = new ExceptionManager(policies);
ExceptionPolicy.SetExceptionManager(exManager);
}
實際上,我現在正在就如何正確處理WCF Faults和EAB進行非常相似的研究。 我認為這篇文章可能對您非常有用。 我還沒有嘗試過,但是看起來沒有那么沉悶。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.