因此,我試圖在我的WCF服務中使用Enterprise Library爲我執行一些與異常相關的工作。使用自定義異常處理程序拋出FaultException EL WCF
我的想法是爲「NullReferenceException」設置一個「自定義異常處理程序」,並在「自定義異常處理程序」中創建FaultException異常。
我的理解是,這個「新」異常會使它跨越網絡,我會在客戶端捕獲它。
更好地瞭解一些代碼:
WCF服務:
[ServiceContract(Name="MyService", ConfigurationName="MyNamespace.MyService")]
[ExceptionShielding("PolicyName")]
public interface IMyService
{
[OperationContract]
[FaultContract(typeof(MyFaultContract))]
string Method(String Param);
}
public class MyService : IMyService
{
public string Method(String Param)
{
throw new NullReferenceException("code-created null message here");
}
}
定義異常處理程序:(企業庫)
public class MyExceptionHandler : IExceptionHandler
{
public MyExceptionHandler(NameValueCollection collection) { }
public MyExceptionHandler() { }
public System.Exception HandleException(System.Exception exception,
Guid handlingInstanceId)
{
MyFaultContract details = new MyFaultContract();
if (exception is NullReferenceException)
{
details.ErrorCode = MyFaultCode.NullReferenceException;
details.OriginalMessage = exception.Message;
details.MyMessage = "Null Reference exception here!";
}
return new FaultException<MyFaultContract>(details);
}
}
映射的NullReferenceException
應用程序配置文件中的「自定義異常處理程序「:
<exceptionPolicies>
<add name="PolicyName">
<exceptionTypes>
<add name="NullReferenceException" type="System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="ThrowNewException">
<exceptionHandlers>
<add type="MyExceptionHandler, MyApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
name="MyExceptionHandler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
而這預計將趕上這的FaultException終於客戶端代碼:
MyService.MyServiceClient client = new MyService.MyServiceClient();
client.Open();
try
{
string result = client.Method(string parameter);
}
catch (System.ServiceModel.FaultException<MyService.MyFaultContract> ex)
{
// where I think exception should end up
}
catch (System.ServiceModel.FaultException ex)
{
// general FaultException
}
而是我得到的ProtocolException,指出答覆需要採取行動:操作接收
回覆消息「方法'採取行動''。 但是,您的客戶端代碼需要採取行動 'http://tempuri.org/MyService/MethodResponse'。
我在做什麼錯?是否有可能在「自定義異常處理程序」中返回(不顯式拋出)具有自定義FaultContract的FaultException?
任何意見表示讚賞。
更新: 正如你所看到的,後處理,在「自定義異常處理程序」操作設置爲「ThrowNewException」。 如果我將它更改爲「NotifyRethrow」,我不會再聲稱「ProtocolException」了! 而是,客戶端捕獲常規「FaultException」(不是自定義類型)。
現在的問題是爲什麼原始的自定義類型的FaultException不能通過電線。
更新2 我忘了提到的一件事是,我的WCF服務運行在ServiceHost中,而不是在IIS下。所以基本上我有一個Windows服務創建一個ServiceHost並通過這個ServiceHost暴露Service1接口。
我認爲這可能與此問題有關的原因是Enterprise Library聲稱它處理整個應用程序中的異常,而不僅僅是在服務範圍內。也許這會導致異常被拋出太晚?還是不在正確的水平?
更新3
感謝您的職位! 你是對的,我弄亂自定義處理程序的唯一原因是因爲我想設置MyFaultCode的值。 我試過你的建議 - 配置了2個處理程序。
首先是自定義處理程序並捕獲NullReference異常。它比使用MyFaultContract字段引發新的異常 - MyApplicationException。
然後,我配置了第二個處理程序 - 內置的「Fault Contract Exception Handler」,它捕獲MyApplicationException,創建新的FaultException並自動將MyApplicationException中的MyFaultcontract映射到新創建的FaultException。
WCF客戶端仍捕獲通用的FaultException,而不是定製合同。
感謝您指出此解決方案。我試了一下,它似乎做了我現在需要的。它真的感覺......低水平。我的意思是你正抓住當異常試圖通過線路並執行一些邏輯的時刻。對其他團隊成員來說可能不完全透明,但肯定會做我需要的。再次感謝! – iEddie 2012-01-12 15:01:45