简体   繁体   中英

Strange behavior when wcf exception

I creating an DivisionByZero exception. So I am expecting to catch the exception int the catch (Execption ex) but I am catching the exception in Catch (CommunicationException ex)

The message says Exception. See details. System.DivideByZeroException: Attempted to divide by zero.

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 Service

[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; }
}

Can anyone explain why to me?

I got it should be like this.

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;
}

When using SOAP, WCF sends faults over the wire. In the client API, they are exposed via FaultException<T> (where T is the fault contract type), which inherits from CommunicationException .

So you can catch FaultException<GeneralException> .

But if all you're doing is wrapping exceptions with this GeneralException object and sending them to the client, there's a built-in WCF mechanism for that. Apply the following attribute to your service:

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

Remove the try..catch block from your method. WCF will automatically catch the exception and send over the wire an ExceptionDetail object. So in your client code:

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

Note that this is not a recommended practice, since you're exposing server stack traces to the client. Instead of sending over exceptions, you can declare fault contracts (which can be any valid data contract, not just exception objects) and send them to the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM