Handling Exceptions in WCF Applications


In this article I will explain the use of structured exception handling using try catch blocks. Since service oriented applications are called by any clients irrespective of the technology, we should handle exceptions in a different way. Since it is not technology specific, we need some generic exception methodology in this case.

WCF unified programming model helps to build secure, reliable and interoperable applications.Since it is not technology specific, we need some generic exception methodology in this case.
In WCF, we can handle exceptions 2 ways:
a) By using .net Exception objects
b) By using SOAP fault messages

Since SOAP faults are expressed in XML format, it is highly interoperable and any clients can easily understand it. There are 2 types of SOAP defaults: declared and undeclared. For declared SOAP faults we must specify [FaultContractAttribute] attribute in the operations where in case of undeclared SOAP faults are not specified in the contract for the operation.

It is always a good practice to declare faults using [FaultContractAttribute] attribute and provide only minimum information in faults in order to minimize the information disclosure to the client. In .Net, System.ServiceModel namespace provides generic Fault Exception Class which can be used to raise SOAP fault exception. Here T represents any objects that can be serialized.

We can send service exception to the client in 3 different ways.

1)Throwing exception using Exception Class

Step 1: Create sample Service with some operation and throw some general exception.


//Service interface
[ServiceContract()]
public interface IMathService
{
[OperationContract()]
int AddNum(int num1, int num2);
}

//Service implementation
public class MathService : IMathService
{

public int AddNum(int num1, int num2)
{
//Do something
throw new Exception("Error while adding number");

}

}


Step 2: Write client side code which will consume the service.


try
{
MathServiceProxy.MathServiceProxy proxy
= new MathServiceProxy.MathServiceProxy ();
Console.WriteLine("Sum of two numbers... 5+5 =" + proxy.AddNum(5, 5));
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}


Here even though I have written to throw some exception in the service, the client will receive following message from WCF.
"The server was unable to process the request due to an internal error. For more information about the error, either turns on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs." This means exceptions are not handled properly.

2)Throwing exception using FaultException class

Here FaultException class comes into picture. So if you want to send some exception information from service to client, we can make use of this .net built in Fault Exception class. You can modify the above service implementation class as follows.


//Service implementation
public class MathService : IMathService
{
public int AddNum(int num1, int num2)
{
//Do something
throw new FaultException("Error while adding number");

}
}


Now if any exception happens in the service, the client will receive following message from the service.

"Error while adding number".

3)Throwing with strongly typed fault.

We can also create our own custom type and send the error information to the client using FaultContract attribute. In order to create custom exception we need to follow the below mentioned steps.

i)Define the exception class using the DataContract attribute and specify the fields you want to return in the exception with DataMember attribute.


[DataContract()]
public class CustomServiceException
{
[DataMember()]
public string ExceptionMessage;
[DataMember()]
public string InnerException;
[DataMember()]
public string StackTraceInfo;
}


ii)Define the service operation with the FaultContract attribute and specify the type name.


[ServiceContract()]
public interface IMathService
{
[OperationContract()]
[FaultContract(typeof(CustomServiceException))]
int AddNum(int num1, int num2);
}



iii)Raise the exception from the service.


public int AddNum(int num1, int num2)
{
//Do something
CustomServiceException ex = new CustomServiceException();

ex.ExceptionMessage = "Error while adding 2 numbers.";

ex.InnerException = "Inner exception message from serice";

ex.StackTraceInfo = "Stack Trace message from service.";

throw new FaultException(ex,"Testing") ;

}




On the client side, we can capture the service exception if any as follows.


try
{
MathServiceProxy. MathServiceProxy proxy
= new MathServiceProxy. MathServiceProxy ();
Console.WriteLine("Sum of two numbers... 5+5 =" + proxy.Add(5, 5));
Console.ReadLine();
}
catch (FaultException ex)
{
//Process the Exception
}


Comments

Author: Siva Prasad26 Mar 2012 Member Level: Gold   Points : 0

Its nice article. Thanks for posting.

Author: Siva Prasad07 Jul 2012 Member Level: Gold   Points : 1

System.ServiceModel namespace is missing.
The code should be as below.


catch (System.ServiceModel.FaultException ex)
{
Response.Write(ex.Message);
}

Author: Siva Prasad07 Jul 2012 Member Level: Gold   Points : 1

throw new FaultException(ex, "Testing"); line giving error as

1. cannot convert from 'WcfFaultExceptionClass.CustomServiceException' to 'string'.

2. cannot convert from 'string' to 'System.ServiceModel.FaultCode'

Guest Author: Harry25 Apr 2013

Its simple to understand and very nice article.Thanks for posting this



  • Do not include your name, "with regards" etc in the comment. Write detailed comment, relevant to the topic.
  • No HTML formatting and links to other web sites are allowed.
  • This is a strictly moderated site. Absolutely no spam allowed.
  • Name:
    Email: