Wednesday, July 15, 2015

Types of Contracts in WCF


In this discussion, we will discuss about the types of Contracts in WCF. But before we start, role of Contracts can be summarized as:

Contracts in WCF make it possible for a service to be created and exchange data between the service and the client application. 

Following types of Contracts are available in WCF:

1. ServiceContract: This is the basic contract type which makes it possible to expose a service to the client applications. This is basically a class level attribute. Any class which needs to be exposed as a service to client, has to be decorated with this attribute on it's definition. For example, a class which provides different operations on an entity of type Employee, as a service to client, will have this attribute added on its definition.

[ServiceContract]
public class Employee
{
    // Your service Methods
}

An important point, this attribute can be added on an interface as well.


2. OperationContract: Once we create a class which will provide services to client, we will add the methods which should be available to client for calling. This is done through the use of the OperationContract attribute. Once this attribute is added, this operation becomes available for client to access. If this contract is not added, client cannot access the method, even if it is a public method.

For example, in above class, if we need to make any method callable by client, we need to add the OperationContract attribute.

[ServiceContract]
public class Employee
{
    [OperationContract]
    public void GetData()
    {
    }
 
    // Not accessible by client as the OperationContract attribute is missing.
    public void DeleteData(Int32 Id )
    {
    }
}

3. DataContract: Now we have the Service class and it's methods. It's turn to configure the data the we would like to be exchanged between  the client and the server. This could be of type Int32, String etc. Exchange of this type of data types is fine. But if we need to pass data of any complex/POCO object, we need to use the DataContract attribute on that object.

For example, if we need to use EmployePOCO type as input parameter or return type of any function in our above service, we need to mark this class with DataContract attribute.

[DataContract]
public class EmployeePOCO
{
    // Class methods and properties go here.
}

4. MemberContract: Normally we use the DataContract to exchange message between the client and server. Sometimes we may need to send the data in either SOAP message header or body. This is done through the use of the MemberContract attribute.

This attribute along with 2 more attributes MessageHeader and MessageBodyMember, allows us to define how the data is being sent through the SOAP message. MessageHeader allows data to be passed in SOAP header and MessageBodyMember allows to send the data through the SOAP body.

For example, we may need to send sensitive data into SOAP header. For this, we use the MessageContract on the complex type and MessageHeader on the property which needs to be sent through the SOAP header.

[MessageContract]
public class UserData
{
  [MessageHeader]
  public string Password
   {
       get;
       set;
   }
   [MessageBodyMember]
   public string UserName
   {
       get;
       set;
   }
}


5. FaultContract: By default the exceptions that occur in a service are not sent to the client. If we throw exception of the type FaultException, it sends the actual exception details to the client. But this is not a good practice that client should never know about the actual technical issue. But it is also important to send the information to client about what has happened in service.

This is where FaultContract helps us. We create a custom class say ExceptionData with properties which specify a custom ErrorMessage and ErrorCode. Then we apply the FaultContract<T> attribute where T is of type ExceptionData, to our method for which we need to pass the custom error message.

[DataContract]
public class ExceptionData
{
  [DataMember]
  public string ErrorMessage
   {
       get;
       set;
   }
   [DataMember]
   public string ErrorCode
   {
       get;
       set;
   }
}

Apply the FaultContract on the method as:

[ServiceContract]
public class Employee
{
    [OperationContract]
    [FaultContract(typeof(ExceptionData))]
    public void GetData()
    {
    }
}

After this, return the FaultException of the type ExceptionData from the method :

[ServiceContract]
public class Employee
{
    [OperationContract]
    public void GetData()
    {
      try
          {
          }
     catch
         {
               ExceptionData exceptionData = new ExceptionData();
               exceptionData.ErrorMessage = "Incorrect parameter passed";
               exceptionData.ErrorCode  = "500";
               throw new FaultException<ExceptionData>(exceptionData);
         }
    }
}

So this was about the concept of Contracts in WCF. Hope you enjoyed reading it. Happy Coding...!!!

No comments:

Post a Comment