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
{
}
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()
{
}
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
{
}
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...!!!