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.)
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.)
try
{
SqlConnection con = new SqlConnection(StrConnectionString);
con.Open();
myServiceData.Result = true;
}
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:
- Service Implementation in ASP.NET
- 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.
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
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(ServiceData))]
ServiceData TestConnection(string strConnectionString);
}
[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.
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
{
public class Service1 : IService1
{
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.
<services>
<service name="FaultContractSampleWCF.Service1"
behaviorConfiguration="FaultContractSampleWCF.Service1Behavior">
<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.
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();
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.