[英]WCF FaultException IErrorHandler - Not returning to client and causing timeout exception
我正在嘗試在使用iis和net.tcp的WCF服務中實現IErrorHandler。
我設置了一個方案以在服務器中引發DivideByZeroException。 IErrorHandler正在按預期觸發。
FaultException沒有返回到客戶端,並且我收到超時異常。 我也沒有在事件日志中找到任何信息/異常。
這是演示代碼。 http://www.fileswap.com/dl/gQFlVsZK7M/ (請單擊慢速下載圖像)
編輯1(從存檔中添加代碼,以供所有人查看):
服務合同:
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(DivideByZeroException))]
string GetData(int value);
[OperationContract]
[FaultContract(typeof(DivideByZeroException))]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
服務實施:
public class Service1 : IService1
{
public string GetData(int value)
{
int i = 0;
//division by zero!
int y = 10/i;
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
IErrorHandler的實現:
public class WcfErrorHandler : IErrorHandler
{
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
var v = error as DivideByZeroException;
if (v != null)
fault = Message.CreateMessage(
version,
new FaultException<DivideByZeroException>(v, new FaultReason(v.Message)).CreateMessageFault(),
"http://the.fault.action");
}
public bool HandleError(Exception error)
{
return true;
}
}
ConsoleApplication1中的ServiceReference未更新,並且不包含故障契約屬性。 在將.NET用於服務和客戶端時,最好在它們之間共享DataContract和ServiceContract。
對於測試,您可以在ConsoleApplication1應用程序中引用WcfService1庫。 當您這樣做時,請按照下列步驟操作:
ConsoleApplication1中的app.config:
<client> <endpoint address="net.tcp://localhost/WcfService1/Service1.svc" binding="netTcpBinding" contract="WcfService1.IService1" name="NetTcpBinding_IService2"> </endpoint> </client>
客戶代碼:
try { var fact = new ChannelFactory<WcfService1.IService1>("NetTcpBinding_IService2"); var proxy = fact.CreateChannel(); var ves = proxy.GetData(1); Console.WriteLine(ves); } catch (FaultException<DivideByZeroException> exp) { Console.WriteLine(exp.Detail); }
服務代碼(我更喜歡捕獲異常,使其盡可能接近導致它的代碼,然后引發具體的故障異常):
public string GetData(int value) { try { int i = 0; int y = 10/i; return string.Format("You entered: {0}", value); } catch (DivideByZeroException d) { throw new FaultException<DivideByZeroException>(d); } }
您的IErrorHandler:
public class WcfErrorHandler : IErrorHandler { public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { if (error is FaultException) { //do nothing as it's already FaultException //you should do a transformation only in the case it's required } else { // Generate fault message manually including the exception as the fault detail MessageFault messageFault = MessageFault.CreateFault( new FaultCode("Sender"), new FaultReason(error.Message), error); fault = Message.CreateMessage(version, messageFault, null); } } public bool HandleError(Exception error) { //here you can log an exception return true; } }
PS看來您托管的服務不正確。 為了測試它,我在ConsoleApplication1中引用了WcfService1。 並執行以下操作:
在ConsoleApplication1的app.config中添加以下行:
<services> <service name="WcfService1.Service1" behaviorConfiguration="CalculatorServiceBehavior"> <endpoint address="" binding="netTcpBinding" contract="WcfService1.IService1" /> <!--<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> --> <host> <baseAddresses> <add baseAddress="net.tcp://localhost/WcfService1/Service1.svc"/> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="CalculatorServiceBehavior"> <serviceDebug includeExceptionDetailInFaults="True" /> <errorHandler /> </behavior> </serviceBehaviors> </behaviors> <extensions> <behaviorExtensions> <add name="errorHandler" type="WcfService1.ErrorHandlerExtension, WcfService1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/> </behaviorExtensions> </extensions>
在客戶致電服務之前,我已經開始服務:
private static void Main(string[] args) { var host = new ServiceHost(typeof(WcfService1.Service1)); host.Open(); ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.