Click here to Skip to main content
15,860,844 members
Articles / General Programming / Exceptions

Fault Contract - Handling Errors in WCF and A Very Simple WCF Service Implementation

Rate me:
Please Sign up or sign in to vote.
4.69/5 (38 votes)
31 Mar 2014CPOL3 min read 238K   2.7K   60   27
Fault Contract - Handling errors in WCF and a simple WCF service implementation

Introduction

What is the use of FaultContract?

In simple WCF Service errors/Exceptions can be passed to the Client (WCF Service Consumer) by using FaultContract.

How do you handle errors in ASP.NET? It's very simple - just by adding the simple Try & Catch blocks. But when you come to WCF Service, if any unexpected error occurred (like SQL server down/Unavailability of data/Divide By Zero) in service, then error/Exception details can be passed to Client by using Fault Contract.

I am giving extensive training's on this topic and all other .Net related training's like ASP.NET, C#.NET, ASP.NET MVC, WCF, WPF & SQL Server. I request you to visit my website here http://onlinedotnet.com

Once you are done reading this article, please go through the Fault Contract Interview questions and answers here.

Step by step explanation with screenshots here.

False Assumption

Most people think that we can't throw FaultException in catch block. It should be only based on some condition (if condition). But it is a false assumption. The main objective is, any type of exceptions(Predicted or Unpredicted) from service to be passed to Client (WCF Service consumer).

Predicted: (Divide By Zero/Channel Exceptions/Application exceptions etc.)

C#
public void Divide(float number, float divideBy)
      {
          If(dividBy ==0)
          {
            myServiceData.Result = false;
            myServiceData.ErrorMessage = "Invalid Operation.";
            myServiceData.ErrorDetails = "Can not divide by 0.";
            throw new FaultException<ServiceData>(myServiceData);
          }
          return number/divideBy;
      }
UnPredicted: (which I explained in this article like connection failures/SQL Server down/Transport errors/Business logic errors.)
C#
try
            {
                SqlConnection con = new SqlConnection(StrConnectionString);
                con.Open();
                myServiceData.Result = true;
             //Your logic to retrieve data & and return it. 
             //If any exception occur while opening the connection or any other 
             //unexpected exception occur it can be thrown to 
             //Client (WCF Consumer) by below catch blocks.
           }
            catch (SqlException sqlEx)
            {
                myServiceData.Result = true;
                myServiceData.ErrorMessage = "Connection can not open this " + 
                   "time either connection string is wrong or Sever is down. Try later";
                myServiceData.ErrorDetails = sqlEx.ToString();
                throw new FaultException<ServiceData>(myServiceData, sqlEx.ToString());
            }
            catch (Exception ex)
            {
                myServiceData.Result = false;
                myServiceData.ErrorMessage = "unforeseen error occurred. Please try later.";
                myServiceData.ErrorDetails = ex.ToString();
                throw new FaultException<ServiceData>(myServiceData, ex.ToString());
            }

Using the Code

This is a very simple WCF service implementation to understand the usage of the FaultContract. Here I am implementing the TestConnection() method in the WCF service. This method tries to open some SQL Server connection. If any errors occur while opening the connection, it throws the error details to the client by using the Fault Contract.

Here my solution contains 2 projects:

  1. Service Implementation in ASP.NET
  2. Consuming the service in Console application

Note: This article is not written to test the connection string. This is to understand the usage of FaultContract. So I have taken this basic example to explain to you better.

1. Service Implementation

Create a WCF Service application project and implement the service with the following code.

The TestConnection() method added with FaultContract attribute in IService1 interface. It means that service errors should be passed to the client with the type of ServiceData class.

ServiceData class is DataContract class. The Error & Success message details to be added to this data members.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace FaultContractSampleWCF
{
    // NOTE: You can use the "Rename" command on the
    // "Refactor" menu to change the interface name
    // "IService" in both code and config file together.
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [FaultContract(typeof(ServiceData))]
        ServiceData TestConnection(string strConnectionString);
    }

    // Use a data contract as illustrated in the sample
    // below to add composite types to service operations.
    [DataContract]
    public class ServiceData
    {
        [DataMember]
        public bool Result { get; set; }
        [DataMember]
        public string ErrorMessage { get; set; }
        [DataMember]
        public string ErrorDetails { get; set; }
    }
}

Here I am implementing the IService1 interface. This interface contains only one method TestConnection() with one input parameter StrConnectionString. For this input parameter SQL Server connection details should be passed from the client side.

Note: This example is only to understand the basic use of Fault Contract. This article doesn't concentrate on service security. You can try this article from your localhost SQL connection by passing valid & invalid connection string details.

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Data.SqlClient;

namespace FaultContractSampleWCF
{
    // NOTE: You can use the "Rename" command on the "Refactor"
    // menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        /// <summary>
        /// Implement the TestConnection method.
        /// </summary>
        /// <returns></returns>
        public ServiceData TestConnection(string StrConnectionString)
        {
            ServiceData myServiceData = new ServiceData();
            try
            {
                SqlConnection con = new SqlConnection(StrConnectionString);
                con.Open();
                myServiceData.Result = true;
                con.Close();
                return myServiceData;
            }
            catch (SqlException sqlEx)
            {
                myServiceData.Result = true;
                myServiceData.ErrorMessage = "Connection can not open this " + 
                   "time either connection string is wrong or Sever is down. Try later";
                myServiceData.ErrorDetails = sqlEx.ToString();
                throw new FaultException<ServiceData>(myServiceData, sqlEx.ToString());
            }
            catch (Exception ex)
            {
                myServiceData.Result = false;
                myServiceData.ErrorMessage = "unforeseen error occurred. Please try later.";
                myServiceData.ErrorDetails = ex.ToString();
                throw new FaultException<ServiceData>(myServiceData, ex.ToString());
            }
        }
    }
}

Web.config

Note: The following endpoint details are automatically added to web.cofig when you create a WCF Service Project.

XML
<services>
  <service name="FaultContractSampleWCF.Service1" 
      behaviorConfiguration="FaultContractSampleWCF.Service1Behavior">
    <!-- Service Endpoints -->
    <endpoint address="" binding="wsHttpBinding" contract="FaultContractSampleWCF.IService1">         
      <identity>
        <dns value="localhost"/>
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  </service>
</services>

2. Consuming the Service in Console Application

Create a new Console project and give the above service reference. Here, we are creating an object to the Service1Client class and calling the TestConnection() method by passing the connection string. If connection succeeds, then it shows "Connection Succeeded" message. If unable to open connection, then it moves to the catch block and displays the appropriate error.

C++
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Client_FaultContractSampleWCF.MyServiceRef;
using System.ServiceModel;

namespace Client_FaultContractSampleWCF
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Service1Client objServiceClient = new Service1Client();
                //Pass the connection string to the TestConnection Method.
                ServiceData objSeviceData = objServiceClient.TestConnection(
                  @"integrated security=true;data source=localhost;initial catalog=master");
                if (objSeviceData.Result == true)
                    Console.WriteLine("Connection Succeeded");
                Console.ReadLine();
            }
            catch (FaultException<ServiceData> Fex)
            {
                Console.WriteLine("ErrorMessage::" + Fex.Detail.ErrorMessage + Environment.NewLine);
                Console.WriteLine("ErrorDetails::" + Environment.NewLine + Fex.Detail.ErrorDetails);
                Console.ReadLine();
            }
        }
    }
}

Summary

Hope this article is useful to understand the usage of the FaultContract. This article is focused on how to implement a basic WCF service and how to handle the errors. Please don't forget to rate it if you like it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) HCL Technologies
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionUseful Pin
frikrishna15-May-17 15:03
frikrishna15-May-17 15:03 
Questionin VB .Net: 'errors' is a class type and cannot be used as an expression Pin
BogdanConstantin26-Jan-17 2:43
professionalBogdanConstantin26-Jan-17 2:43 
SuggestionThanks. Pin
phillipvoyle23-Jul-15 15:50
phillipvoyle23-Jul-15 15:50 
QuestionHow to catch infrastructure exceptions i.e. CommunicationException on server side ? Pin
Alemvik22-Jan-15 6:52
Alemvik22-Jan-15 6:52 
GeneralMy vote of 5 Pin
Vishal Palan4-Jul-14 20:56
Vishal Palan4-Jul-14 20:56 
QuestionFaultContract benefits in WCF service Pin
Manas_Kumar12-Mar-14 20:07
professionalManas_Kumar12-Mar-14 20:07 
QuestionFault Contract Pin
Sanju720-Feb-14 0:41
Sanju720-Feb-14 0:41 
AnswerRe: Fault Contract Pin
irsha7-Mar-14 19:48
irsha7-Mar-14 19:48 
GeneralMy vote of 4 Pin
Shrilata Ellaboina29-May-13 1:16
Shrilata Ellaboina29-May-13 1:16 
QuestionMy vote of 4 Pin
ssnaik8427-May-13 7:31
ssnaik8427-May-13 7:31 
GeneralNice basic article Pin
The Sanjeev Majgotra16-May-13 20:43
The Sanjeev Majgotra16-May-13 20:43 
Generalgood explanation. Pin
Mohan_J12-Apr-13 20:57
Mohan_J12-Apr-13 20:57 
GeneralMy vote of 4 Pin
div_gusain8-Feb-13 19:23
div_gusain8-Feb-13 19:23 
QuestionThe control does not go to client side catch block Pin
Imran_hus3-Dec-12 19:56
Imran_hus3-Dec-12 19:56 
QuestionThe control does not go to client side catch block Pin
Imran_hus3-Dec-12 19:34
Imran_hus3-Dec-12 19:34 
QuestionCan return type and FaultContract type be different. Pin
Gadikrindi Suman23-Nov-12 4:06
Gadikrindi Suman23-Nov-12 4:06 
QuestionWorked for me Pin
jumbojs6-Nov-12 3:12
jumbojs6-Nov-12 3:12 
QuestionNice work Pin
felixntny11-Oct-12 18:26
felixntny11-Oct-12 18:26 
GeneralMy vote of 5 Pin
Member 313707813-Sep-12 20:42
Member 313707813-Sep-12 20:42 
QuestionWhat about Silverlight? Pin
sumus16-Jul-12 18:32
sumus16-Jul-12 18:32 
GeneralMy vote of 3 Pin
ganesan25107-May-12 20:29
ganesan25107-May-12 20:29 
GeneralMy vote of 4 Pin
Makassi7-May-12 9:57
Makassi7-May-12 9:57 
QuestionMy reason for giving a vote of 3 Pin
sucram2-May-12 5:55
sucram2-May-12 5:55 
AnswerRe: My reason for giving a vote of 3 Pin
sergio treiger7-May-12 5:39
sergio treiger7-May-12 5:39 
GeneralMy vote of 3 Pin
sucram2-May-12 5:54
sucram2-May-12 5:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.