wcf异常时的奇怪行为

时间:2014-02-20 14:56:48

标签: c# .net wcf

我创建了DivisionByZero异常。 所以我期望捕获catch中的异常(Execption ex),但我在 Catch(CommunicationException ex)

中捕获异常

消息显示异常。查看详细信息。 System.DivideByZeroException:尝试除以零。

Service.YourClientProxy client = new Service.YourClientProxy();

try
{
    client.DivisionByZeroException();
    client.Close();
}
catch (CommunicationException ex)
{
    client.Abort();
}
catch (TimeoutException ex)
{
    client.Abort();
}
catch (Exception ex)
{
    client.Abort();
    throw;
}

Wcf服务

[OperationContract]
[FaultContract(typeof(GeneralException))]
public void DivisionByZeroException()
{
    try
    {
        int a = 0;
        int c = 1 / a;
    }
    catch (Exception ex)
    {
        GeneralException exception = new GeneralException(ex.ToString());
        throw new FaultException<GeneralException>(exception, "Exception. See details.\n" + ex.ToString());
    }
}

[DataContract]
public class GeneralException
{
    public GeneralException(string message)
    {
        this.Message = message;
    }

    [DataMember]
    public string Message { get; set; }
}

任何人都可以向我解释原因吗?

2 个答案:

答案 0 :(得分:0)

我知道应该是这样的。

Service.YourClientProxy client = new Service.YourClientProxy();

try
{
    client.DivisionByZeroException();
    client.Close();
}
catch (FaultException ex)
{
    client.Abort();
}
catch (CommunicationException ex)
{
    client.Abort();
}
catch (TimeoutException ex)
{
    client.Abort();
    throw;
}

答案 1 :(得分:0)

使用SOAP时,WCF通过线路发送故障。在客户端API中,它们通过FaultException<T>(其中T是错误契约类型)公开,它继承自CommunicationException

所以你可以抓住FaultException<GeneralException>

但是,如果你所做的只是用这个GeneralException对象包装异常并将它们发送到客户端,那么就有一个内置的WCF机制。将以下属性应用于您的服务:

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
class MyService
{
   public void DivisionByZeroException()
   {
      int a = 0;
      int c = 1 / a;
   }
}

从方法中删除try..catch块。 WCF将自动捕获异常并通过线路发送ExceptionDetail对象。所以在你的客户代码中:

try
{
    client.Exception();
    client.Close();
}
catch (FaultException<ExceptionDetail> ex)
{ 
    // handle it; ex.Detail contains the server exception data
}

请注意,这不是推荐的做法,因为您将服务器堆栈跟踪暴露给客户端。您可以声明故障合同(可以是任何有效的数据合同,而不仅仅是异常对象),而不是发送异常,并将它们发送给客户端。