Exception Handling in WCF

MinalS's Avatar author of Exception Handling in WCF
When user communicates with WCF service, it can result in errors like invalid data type, type conversion, or service not available etc and can be handled using exceptions..
During the communication various errors like invalid data type, type conversion, or service not available can occur. The application terminates abruptly when such errors occur. User can avoid the errors and make the application execute smoothly by providing error handling code. This process is known as exception handling.

If an unhandled exception occurs, an unhandled exception occurs in a WCF service. A default exception is thrown and the communication between the service and the client application is disconnected. The service supports any client type communication using a standard protocol as SOAP protocol. The exception thrown by the WCF service should be converted into SOAP format.

Faulted Channel



The communication between the client and the server is possible through the communication channels. When the channel is faulted due to the exception, the communication between the client and server is halted. The new proxy is created when the channel is detected as faulted. The client application detects the state of the channel after each fault. The State property of the channel is used to detect the fault.

Code:
protected void Divide_Click ( object sender, EventArgs e)
{
    ServiceReference1.ServiceClient obj= new ServiceReference1.ServiceClient ();
    try
            {
        int num=Convert.ToInt32( TextBox1.Text);
        int den=Convert.ToInt32 ( TextBox2.Text);
        label.Text=obj.DivideNumber( num, den).ToString();
            }
    catch ( FaultException e)
            {
        if ( obj.State==CommunicationState.Faulted)
        {
            label.Text="Communication Channel has been faulted";
            this.AddProxy();
        }
    }
}

public void AddProxy()
{
ServiceReference1.ServiceClient obj=new ServiceReference1.ServiceClient();
}
In the above code, the proxy object named as obj is created. The object is about the WCF service. After creating the object, the DivideNumber() method is called. If there is an exception occurred, the State property is used to check it. If the channel is detected as faulted, the message is displayed and the proxy is recreated.

Communicating the Exception Details



In a WCF service when an exception is thrown, the details of the exception are not sent to the client exception. In order to send the details to the client application, the value of the includeExceptionDetailsInFaults attribute of the serviceDebug element is set to true. All the settings are performed in the web.config file. The following code snippet shows how user can set the value of the attribute.

Code:
<serviceDebug includeExceptionDetailInFaults="true" />

Implementing the Exception Handling



Exception handling is used to handle the exceptions that occur in a WCF service. To implement exception handling in a WCF service, the following classes of the System.ServiceModel namespace are used.
  1. The FaultException class
  2. The generic FaultException class

1. The FaultException class

The FaultException class is the base class used to handle the exceptions in a WCF application. The class serializes the messages thrown by the WCF service into the SOAP fault.

The following code snippet shows the use of the FaultException class. Add the following code in the Service1.svc.cs class.

Code:
public string GetData (int value)
{
     try
    {
            if ( value ==0)
            {
                    MyException mx=new MyException ();
                mx.message="Value cannot be zero";
                throw new FaultException <MyException>(mx);
            }
                return string.Format ("The values entered is {0}", value);
    }

    catch (NotFiniteNumberException)
    {
    }
        return string.Format ("The values entered is {0}", value);
}
Add the following code in the IService1.cs class in the WCF application.

Code:
[ServiceContract]
public interface IService1
{
    [OperationContract]
            [FaultContract(typeof(MyException))]
    string GetData ( int value);
}

[DataMember]
public string message;
Create a client application to access the service. Add a console application to the solution and add the following code.

Code:
class Program
{
    public static void Main( string[] args)
    {
        ServiceReference1.ServiceClient obj= new ServiceReference1.ServiceClient ();
        try
        {
            Console.WriteLine ( "Enter the number");
            int x=Convert.ToInt32 ( Console.ReadLine ());
            string a=obj.GetData (x);
            Console.WriteLine (a);
        }
        catch ( FaultException<ServiceReference1.myexception> mx)
        {
            Console.WriteLine (mx.Detail.message);
        }
        Console.Read();
    }
}
The output for the code is as shown below:



Using the Fault Code and FaultReason Arguments

The FaultException constructor can take the FaultCode and the FaultReason arguments to describe the reason and code of the SOAP fault. The code snippet mentions the fault code and fault reason.

Code:
public string GetData ( int value)
{
    try
    {
        if ( value ==0)
        {
            MyException mx=new MyException ();
            mx.message="Value cannot be zero";
            throw new FaultException(new FaultReason(" A number cannot be zero"), FaultCode.CreateRecieverFaultCode ( new FaultCode ("NotFiniteNumberException")));
        }
        return string.Format (" You entered the value {0}", value);
    }
}
2. The generic FaultException class

The FaultException class does not contain a specific way to create error handling from the client side. The generic FaultException class is used to implement the logic.

The generic FaultException class accepts the structure of the exception that is serialized. The user defined exception class throws a FaultException and sends the customized message to the client application for the WCF service. The class needs to be exposed in order to perform the following tasks:
  1. Define a user – defined exception class
  2. Define a FaultContract
  3. Throw a FaultException
Define a user – defined exception class

While defining a user defined exception class, user needs to use the [DataContract] and [DataMember] attributes to expose the class and its members

The following code snippet demonstrates the exception class.

Code:
[DataContract]
public class MyFaultException
{
    [DataMember]
    public string message;
}
In the above code, the [DataContract] attribute is used to expose the user – defined exception class, MyFaultException and the [DataMember] is used to expose the message variable.

Define a FaultContract



The [FaultContract] attribute is used to serialize the user defined exception class. It indicates the WCF service for customized error message sent to the client application when an exception is thrown.

The client application is enabled and a proxy is created. The proxy represents user defined class and messages sent to the service. The following code snippet demonstrates the fault sent to the client application.

Code:
[ServiceContract]
public interface IService1
{
    [OperationContract]
    [FaultContract ( typeof( MyFaultException))]
    int Divide( int num, int den);
} 
[DataContract]
public class MyFaultException
{
    [DataMember]
    public string message; 
}

Throw a Fault Exception



When a user needs to provide customize error message, the FaultException is thrown. It has a user defined class as a parameter. The following code snippet shows the user defined exception.

Add the following code in a web form containing two textboxes and a label control.

Code:
try
{
    ServiceReference1.ServiceClient1 obj=new ServiceReference1.ServiceClient1();
    int value1=Convert.ToInt32( TextBox1.Text);
    int value2=Convert.ToInt32( TextBox2.Text);
    Label1.Text=obj.Divide(value1, value2).ToString();
}
catch ( FaultException<ServiceReference1.MyFaultException> faultEx)
{
    Label1.Text=faultEx.Detail.message;
}
The output for the exception is as shown below:



In the above code, the MyFaultException is a user defined class. It is accessed through the object faultEx of the FaultException type. It contains the reference to the user defined class. The message variable is accessed through the Detail property.