Introduction Windows communication foundation is Microsoft's new platform for developing distributed applications using .Net framework. WCF simplifies development of connected applications through a new service oriented programming model. In this article I will explain one of the most sensitive parts of WCF which is contracts.
WCF Contracts Beside addresses and bindings, contacts also play an important role in WCF service. Contracts define certain aspects of the service such as the format and structure of the messages which are sent between the service and the client. Both the service and the client must agree of the types of operations and structures they will use during the period of communication.
Let us start When developing WCF service, you must first define the interface in which you will implement your service
C# |
public interface INewService
{
int AddOperation(int no1, int no2);
}
|
In the pervious code snippet I created an interface using my favorite language C#. This interface named INewService, also I defined only one method named AddOperation which accept two parameters of type "int" and add them then return the result also of type "int". I prefer this example because it is very simple one; I don't want to write complex code in that example to let us focus on WCF not writing complex mathematical code.
Second step is to convert your interface to a WCF contract; you do so by annotating interface with attribute. In the next example I will annotate the INewService with the [ServiceContarct] annotation. This basically announces to the public "I'm WCF Service".
C# |
[ServiceContract()]
public interface INewService
{
[OperationContract]
int AddOperation(int no1, int no2);
}
|
You may notice that the AddOperation method also annotated with [OperationContract] this mean that this method will be available to the service's clients.Now you have completed your first and second steps then you have to inherit that interface and implement its methods, you can do that by defining a Class.
C# |
public class MyService : INewService
{
public int AddOperation(int no1, int no2)
{
return no1 + no2;
}
}
|
Congratulations now you have created your first WCF service code and defined your logic. Actually I love the method in which you can change your interface into WCF contract. Because this method gives you the flexibility to convert your old interfaces simply to new WCF contacts. So the final code will be as the following snippet.
C# |
[ServiceContract()]
public interface INewService
{
[OperationContract]
int AddOperation(int no1, int no2);
}
public class MyService : INewService
{
public int AddOperation(int no1, int no2)
{
return no1 + no2;
}
}
|
There is also a pretty thing here that you don't need to make any changes in the interface implementation (the Class). Now is the time to talk about the three basic contracts used to define WCF service.WCF Contacts In the pervious example, I introduced to you the Service Contract which is one of three basic contacts used to define WCF service.
- Service contract: Define the service and its methods and operations available to the clients.
- Data Contact: Define the data types used in the service.
- Message contract: Provide ultimate control over the formatting of the SOAP messages.
Service Contact
A service contact defines the operations that are available on the service. It also defines the basic message exchange patterns. Service contract expose specified information to the client which enables the client to understand what service has to offer.
Simply you can define the service contact by applying the [ServiceContarct] annotation to an interface or class
C# |
[ServiceContract()] public interface INewService
{
// Add You Methods
}
|
After that you apply the [OperationContact] annotation on all methods in the interface, as the following
C# |
[OperationContract]
public bool IsAuthenticated(string userName, string password);
|
By this simple mechanism you can convert any normal interface to a service contact. The service contract attribute has many parameters to be applied which give you the flexibility to customize your service, such parameters as the Protectionlevel which specify the protection level binding requirements. The following example sets the protection level of the service contract to none.
C# |
[ServiceContract(ProtectionLevel=System.Net.Security.ProtectionLevel.None)]
public interface INewService
{
....
}
|
The [OperationContact] also has many parameters that are available to use with it. Such as IsIniating, IsoneWay and IsTerminating. The following example sets the IsOneWay parameter to false which identify that the service operation will not return a reply message.
C# |
[OperationContract(IsOneWay=false)]
void Checkin(string ID);
|
Data Contracts If you speak English and you want to talk with someone that speaks another language, before you start talk with him. You must agree on which language the conversation will be. As this scenario, in WCF the client and the service must agree on the data that they will pass. Data contracts define the data types used between the client and the service. An important thing to remember here is the serialization and deserialization. Serialization is the process of converting structured data into a format that can be sent over a wire. Deserialization is the opposite process; it takes the data coming in over the wire and converts it back to structured data. The data serialized in order to be exchanged from service to the client and vise versa.
Simply you can define data contracts by applying [dataContract] annotation to a class.
C# |
[DataContract()]
public class userInfo
{
...
...
}
|
You can only apply [dataContract] attribute to a class, enumeration, and structure but not an interface, it can be only annotated with service contract. We have also [datamember] attribute that is applied to all members of the data contract to identify it as a data member.
C# |
[DataContract()]
public class userInfo
{
[DataMember]
public string name;
[DataMember]
public int id;
[DataMember]
public int age;
}
|
Once you have defined the DataContract you can use it in the service contract
C# |
[ServiceContract()]
public interface INewService
{
[OperationContract()]
void NewUser(userInfo info);
}
|
Finally the parameters, you can assign parameters to the data contract attribute such as name and namespace. Data member attribute also has many parameters you can use as
EmitDefaultValue which specifies where or not to serialize the default value for a field being serialized and also
IsRequired which used to inform the serialization engine that a data member must be present. The following code snippet show you how to assign
IsRequired to datamember attribute.
C# |
[DataContract()]
public class userInfo
{
[DataMember(IsRequired=true)]
public string name;
}
|
Message Contracts If you need more control over SOAP messages and you want to customize them. Then you need to use message contracts. First of all I want to define a message; a message is a packet of data containing several pieces of important information being routed from a source to a destination. In WCF all messages are SOAP messages formatted in XML as SOAP envelopes. WCF uses messages to pass data from one point to another.
There are basically three general components that make up a SOAP message.
- The SOAP Envelope
- The SOAP Headers
- The SOAP Body
Message contracts are defined by applying the [MessageContract()] attribute. You then specify the [MessageHeader] and the [MessageBodyMember].
C# |
[MessageContract()]
public class user
{
[MessageHeader]
public string name;
[MessageBodyMember]
public int id;
}
|
Once you have defined the message contract you can enabled the passing of messages between services and clients. The message header attribute maps a SOAP message header to fields and properties of a type marked with the [MessageHeader] attribute. And the [MessageBodyMember] attribute identifies the members who are to be serialized as a SOAP body element.
The following example define a message contract with the message header associated with a public string named UserID, and two message body members Name, and Age.
C# |
[MessageContract()]
public class userInfo
{
[MessageHeader]
public string userId;
[MessageBodyMember]
public int name;
[MessageBodyMember]
public int age;
}
|
Finally, we have [MessageProperty] attribute which specifies those members who will not be serialized into the SOAP messages. But contains data that is included with a custom message
C# |
[MessageContract()]
public class userInfo
{
private string name;
[MessageHeader]
public string userId;
[MessageProperty]
public string name
{
get { return name; }
set { name = value; }
}
}
|
Conclusion This article covered all aspects related to Windows Communication Foundation Contracts, started with the service contracts and how to define it. Then covered some examples of how to use data contracts in service contracts. Finally how to control the message through message contracts.