簡體   English   中英

WCF FaultException IErrorHandler-不返回客戶端並導致超時異常

[英]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庫。 當您這樣做時,請按照下列步驟操作:

  1. ConsoleApplication1中的app.config:

     <client> <endpoint address="net.tcp://localhost/WcfService1/Service1.svc" binding="netTcpBinding" contract="WcfService1.IService1" name="NetTcpBinding_IService2"> </endpoint> </client> 
  2. 客戶代碼:

     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); } 
  3. 服務代碼(我更喜歡捕獲異常,使其盡可能接近導致它的代碼,然后引發具體的故障異常):

     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); } } 
  4. 您的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。 並執行以下操作:

  1. 在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> 
  2. 在客戶致電服務之前,我已經開始服務:

     private static void Main(string[] args) { var host = new ServiceHost(typeof(WcfService1.Service1)); host.Open(); ... 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM