WCF Web Service Custom Exception Error to Client

In WCF, you should not throw standard .NET exceptions – this is contrary to the potentially interoperable nature of WCF – after all, your client could be a Java or PHP client which has no concept of .NET exceptions.

Instead, you need to throw FaultExceptions (which is the standard behavior for WCF).

If you want to convey back more information about what went wrong, look at the generic FaultException<T> types:

SERVER:

public bool Read()
{
    if (IsUserValid() == false)
    {
        throw new FaultException<InvalidUserFault>("User invalid");
    }
}

Or alternatively (as suggested by @MortenNorgaard):

public bool Read()  
{ 
    if (!IsUserValid()) 
    { 
        InvalidUserFault fault = new InvalidUserFault(); 
        FaultReason faultReason = new FaultReason("Invalid user"); 

        throw new FaultException<InvalidUserFault>(fault, faultReason); 
    }   
}

CLIENT:

try
{
   _client.Read();
}
catch (FaultException<InvalidUserFault> e)
{
    MessageBox.Show(e.Message);
    return;
}

You should declare your InvalidUserFault as WCF data contracts and define what members might travel back with that type (i.e. error code, error message etc.).

 [DataContract]
 [Serializable()]
 public class BusinessFault
 {
   ... add your fault members here
 }

And you should then decorate your service methods with the possible faults it can throw:

[FaultContract(typeof(InvalidUserFault)]
[OperationContract]
public bool Read()
.....

Of course, the “quick’n’dirty” hack is to simply define that the server returns exception details in its FaultExceptions:

<serviceBehaviors>
   <behavior name="EmployeeManager_Behavior">
      <serviceDebug includeExceptionDetailInFaults="true"/>
   </behavior>
</serviceBehaviors>

and then you can inspect the FaultException’s .Detail for the actual exception that happened on the server – but again: this is more of a development-time only hack rather than a real solution.

Marc

Leave a Comment