Fault Contract in WCF

This article describes how we can handle errors in a WCF service using Fault Contract.

Introduction
 
In a typical Windows application, we use the try..catch..finally block to handle and catch exceptions. But a try..catch block does not work in WCF services. Being a web application, try..catch does not work unless we throw and bubble up the exception.
 
In WCF, errors can be handled and error message can be conveyed to the client applications using SOAP Fault contract.
 
Fault Contract provides documented view for error accorded in the service to client.
 
Let's see how to use fault contracts in WCF.
 
Example
 
1. I created a service with Add operation which will throw general exception as show below:
  1. //Service interface  
  2. [ServiceContract()]  
  3. public interface ISimpleCalculator {  
  4.  [OperationContract()]  
  5.  int Add(int num1, int num2);  
  6. }  
  7. //Service implementation  
  8. public class SimpleCalculator: ISimpleCalculator {  
  9.  public int Add(int num1, int num2) { //Do something  
  10.   throw new Exception("Error while adding number");  
  11.  }  
  12. }  
2. If we want to send exception information form service to client, we have to use FaultException as shown below
  1. public int Add(int num1, int num2) {  
  2.  //Do something  
  3.  throw new FaultException("Error while adding number");  
  4. }  
Output window on the client side is shown below.
 
Error while adding number.
 
3. We can also create your own Custom type and send the error information to the client using FaultContract.
  1. Define a type using the data contract andspecify the fields you want to return.
  2. Decorate the service operation with theFaultContract attribute and specify the type name.
  3. Raise the exception from the service bycreating an instance and assigning properties of the custom exception.
Step 1:  Defining the type using Data Contract
  1. [DataContract()]  
  2. public class CustomException {  
  3.  [DataMember()]  
  4.  public string Title;  
  5.  [DataMember()]  
  6.  public string ExceptionMessage;  
  7.  [DataMember()]  
  8.  public string InnerException;  
  9.  [DataMember()]  
  10.  public string StackTrace;  
  11. }  
Step 2: Decorate the service operation with the FaultContract
  1. [ServiceContract()]  
  2. public interface ISimpleCalculator {  
  3.  [OperationContract()]  
  4.  [FaultContract(typeof(CustomException))]  
  5.  int Add(int num1, int num2);  
  6. }  
Step 3: Raise the exception from the service
  1. public int Add(int num1, int num2) {  
  2.  //Do something  
  3.  CustomException ex = new CustomException();  
  4.  ex.Title = "Error Funtion:Add()";  
  5.  ex.ExceptionMessage = "Error occur while doing add function.";  
  6.  ex.InnerException = "Inner exception message from serice";  
  7.  ex.StackTrace = "Stack Trace message from service.";  
  8.  throw new FaultException(ex, "Reason: Testing the Fault contract");  
  9. }  
Step 4: On client side, you can capture the service exception and process the information, as shown below
  1. try {  
  2.  MyCalculatorServiceProxy.MyCalculatorServiceProxy proxy = new MyCalculatorServiceProxy.MyCalculatorServiceProxy();  
  3.  Console.WriteLine("Client is running at " + DateTime.Now.ToString());  
  4.  Console.WriteLine("Sum of two numbers... 5+5 =" + proxy.Add(5, 5));  
  5.  Console.ReadLine();  
  6. catch (FaultException < MyCalculatorService.CustomException > ex) {  
  7.  //Process the Exception  
  8. }