WCF Exception Handling

There are two ways for a WCF service to support exception handling:

  1. Defining the serviceDebug.includeExceptionDetailInFaults  attribute to “true” in the hosts .config file
  2. Defining the includeExceptionDetailInFaults attribute to “true” on the service class.

Example:

Config File Solution:

<behaviors>
<serviceBehaviors>
<behavior name=”ServiceBehavior”>
<serviceMetadata httpGetEnabled=”true”/>
<serviceDebug includeExceptionDetailInFaults=”true”/>
</behavior>
</serviceBehaviors>
</behaviors>
Attributed Class Solution:
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class CustomersService : ICustomersService
{
private CustomerDetail customerDetail = null;
… etc
Throwing the Exception
Setting the includeExceptionDetailInFaults to true is your first step in supporting exceptions in WCF. The next step is to have your service throw the FaultException exception (a class in the System.ServiceModel.FaultException namespace). Note that you cannot expect to simply use the typical Exception class when you wish to throw exceptions from the WCF host to the WCF client. To throw exceptions over the WCF bindings you will need to use the FaultException class.
Throwing FaultException Example:
try
{
//Try to do stuff
}
catch
{
throw new FaultException(“Full ruckus!”);
}
Catching FaultException Example:
Now the WCF client can catch the FaultException…
try
{
//Client calls services off the proxy
}
catch(FaultException fa)
{
MessageBox.Show(fa.Message);
}
Distinguish Types of Fault Exceptions
The FaultException class is a generic class for WCF exceptions. In order to determine what type of FaultExceptions occur, you use the FaultCode class.
On the WCF service the FaultCode implementation will look something like this:
try
{
//Connect to a database
}
catch
{
throw new FaultException(“Full ruckus!”, new FaultCode(“DBConnection”));
}
On the WCF client, the FaultCode implementation will look something like this:
try
{
//Call services via the proxy
}
catch(FaultException fa)
{
switch(fa.Code.Name)
{
case “DBConnection”:
MessageBox.Show(“Cannot connect to database!”);
break;
default:
MessageBox.Show(“fa.message”);
break;
}
}
Strong Typed SOAP Faults
The FaultException class represents a generic fault. To implement strongly typed faults over WCF, you can use strongly typed SOAP faults. To do so, you will need to create one or more fault classes and add them to the services Data Contract. In the service contract you will decorate the operations with the FaultContract attribute.
SOAP Fault Example
The Service Contract:
[ServiceContract]
public interface IService
{
[OperationContact]
[FaultContract(typeof(ConnectionFault))] //Decorate the operation with FaultContract attribute setting the type to our arbitrary fault class
[FaultContract(typeof(DataFault))]
string TheOperation();
}
[DataContract]
public class ConnectionFault //This is just a class, but we will be using it for our FaultException type (this is SOAP friendly!)
{
[DataMember]
public string Operation;
[DataMember]
public string Reason;
[DataMember]
public string Details;
}
[DataContract]
public class DataFault //Another class that we will use for SOAP exceptions
{
[DataMember]
public string Operation;
[DataMember]
public string Reason;
[DataMember]
public string Details;
}
The Service:
public string TheOperation()
{
try
{
//Do operation stuff
}
catch(Exception ex)
{
var connectionFault = new ConnectionFault();
connectionFault.Operation = “TheOperation”;
connectionFault.Reason = “Can’t connect to database.”;
connectionFault.Details = ex.Message;
throw new FaultException<ConnectionFault>(connectionFault);
//alternate overload that will display debug information when running client in debug mode
//throw new FaultException<ConnectionFault>(connectionFault, new FaultReason(“Database service is not running”));
}
The Client:
private void CallService()
{
try
{
string serviceResponse = proxy.TheOperation();
}
catch (FaultException<ConnectionFault> fe) //Catch the strongly typed SOAP exception
{
MessageBox.Show(string.Format(“{0}\n\nThe following occurred in {1}:\n{2}”,
fe.Detail.Reason,
fe.Detail.Operation,
fe.Detail.Details),
“Connection problem”);
}
catch (Exception ex) //Catch any other exception type
{
MessageBox.Show(ex.Message);
}
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s