Wednesday, 9 April 2014

Fault Contracts and Exceptions

Fault Contracts
Windows Communication Foundation enables us to specify the fault behavior of our service.
For example
We create a service and this service is consumed by a client. Suppose this service throws an exception. But how can the client be notified of this exception? Because whenever an exception is thrown from a service, it cannot be sent to the client. But if you want to know the reason then a fault contract can help us. We can send information regarding this with the fault.
Faults Vs. Exceptions
The main thing in faults and exceptions is that "faults and exceptions are not the same thing".
An exception is a .Net mechanism. It is used when the program encounters an error. The .Net language allows us to throw, catch and ignore the exception. At some point they should be handled or the .Net runtime will terminate the thread in which the exception was thrown.
Faults refer to the SOAP fault mechanism to transfer error information from a service to a client. WCF provides the FaultException class. Whenever a service throws a FaultException, WCF serializes the information sent to the client.

FaultException
A FaultException is used to send untyped fault data to the client.
FaultException<TDetail>
This generic version is used to send typed fault data to the client. TDetail represents the type parameter for the fault information. Now let's see the example of typed fault data.
Create one WCF Service Application. Add the following segment of code in the Interface. In this code we are using the FaultContract attribute. It is applied to the interface only. Suppose we want to return various types of faults then we need to set the FaultContract attribute multiple times.

    [ServiceContract]
    public interface IService1
    { 
        [OperationContract]
        [FaultContract(typeof(FaultInfo))]
        string Topup(string Operator, string MobileNumber, double Amount);
    } 
    [DataContract()]
    public class FaultInfo
    {
        [DataMember()]
        public string Reason = null;
    }
If we choose to use a typed fault then we need to define a DataContract for the type that holds the error information. In our example we create a datacontract for the FaultInfo class and we create one data member i.e. reason to hold the error information.
Add the following lines of code in the .svc.cs file. In this method we check whether the amount is double or not. If the amount is double then we throw a fault exception.

public string Topup(string Operator, string MobileNumber, double Amount)
    {
        if (Amount == 0.0d)
        {
            FaultInfo fi = new FaultInfo();
            fi.Reason = "Amount should not be in double.";
            throw new FaultException<FaultInfo>(fi,new FaultReason(fi.Reason));
        }
        return "Recharge Successful.";
    }

If the amount is double then we create an object of the "FaultInfo" class and set the information we want to send to the client in the datamember i.e. the Reason. Finally we throw a fault exception of the fault info type.


A bare FaultException may be safe, but it doesn't provide enough information. I may not want to pass the full stack trace, but I want to provide at least basic information about what went wrong. WCF provides multiple ways to do this.

The FaultException class itself includes several ways to provide more information. The FaultException class includes these constructors (among others):
public FaultException(string reason);
public FaultException(string reason, FaultCode code);
public FaultException(FaultReason reason);
public FaultException(FaultReason reason, FaultCode code);

The simplest way to provide information is the first of these: 

try
{
    // do something
}
catch (Exception ex)
{
     myLogger.LogException(ex);
     throw new FaultException("Your request timed out. Please try again later.");
}

The client can capture the FaultException and read the message as follows:
try
{
     // call the web service
}
catch (FaultException ex)
{
     Console.WriteLine(ex.Message);
}

As you can see from the FaultException constructors, you can create a FaultException with a string, a FaultCode, a FaultReason or some combination of these.

The FaultReason class lets you provide the same error message in multiple languages. If you look at the list of FaultException constructors, you will see that you can either provide an error message in a string or a collection of error messages in a FaultReason. You don't need both. 

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

There are 4 sets of errors that clients can expect:

Invalid configuration: when bindings, behaviors or any other configs are in conflict with some other settings.
Communication errors: These are the usual errors caused as the result of network communication issues such as incorrect or unreachable addresses and the unavailability of a network connection. You may receive a CommunicationException as a result this.
Service faults: By default all service side exceptions are sent to the client as FaultException.
Proxy or channel state errors: These types of errors are raised when the channel or the proxy is not in a correct state to allow for communications. For example the proxy could be in the Faulted state and attempting to use that proxy will throw an exception.
 

No comments:

Post a Comment