A few years back, when WCF was introduced, I was very eager to learn about this technology. I got a few chances to work with it and I came across the concept of FaultContract and MessageContract. But I was not able to dig deeper into these concepts. Finally, I decided to spend some time for these concepts of MessageContracts as well.
What a Message Contract is
When using a WCF service, in order to send the data, like any custom class data, developers don't need to do anything except add the DataContract and DataMember attributes on the type of data, that is to be transferred. The developer need not be concerned about serializing the data, converting it into SOAP XML and sending to the client. To check this, let's create a sample application.
Add a new WCF application and add 2 classes named RequestData and ResponseData. RequestData has a property named EmployeeId and ResponseData has properties representing the details about the Id being sent by the client. In order to serialize this data and transfer it using SOAP, we will only add DataContract and DataMember attributes to these classes and there properties respectively.
Next, we will add a method in our service interface, that will take an input of type RequestData and return output of type ResponseData. Depending on the EmployeeId received in the request, it will return data of the user. So our implementation will be like the following:
Now, run the WCF test client, set a sample EmployeeId and invoke the method to see the results. We can see that the request and response SOAP XMLs contain the EmployeeId that we had set and its corresponding details respectively.
This is the normal way of sending the data through the SOAP. Sometimes we may have a situation, where we need to control the way data is being sent, like we may need to send the data in the header of the SOAP or control the overall structure of what data is being sent in the header or body and so on. In that case, using DataContract and DataMember is not the solution.
So let's change some of our existing requirements and approach, where we would like to send the EmployeeId in the header of the request XML and get back the EmployeeName and EmployeeDesignation in the body of the response XML and EmployeeUserName in the header of the response XML. To do this, we need to alter our RequestData and ResponseData classes slightly and decorate them with MessageContract and its related attributes named MessageHeader and MessageBodyMember attributes. For the data that we want to send in the header, we add a MessageHeader attribute and for the data that we want to send in the body XML, we add a MessageBodyMember attribute. On the whole, we add the MessageContract attribute on these classes, so that these can be serialized for transfer. So our changed code becomes:
So we are all set now. We just need to run the WCF test client and invoke the method again and we can see the results.
This is what we changed the code for. We have the EmployeeId in the request header XML and EmployeeUserName in the response header XML. Other details are added to the response body XML. But using this process has some certain restrictions on it. These are:
Any method involving MessageContract types can have only one input parameter and that too must be a MessageContract type.
The return value can be either be void or any type that is of MessageContract type.
So this is the basic implementation of MessageContract. If you need to control the overall structure of the SOAP XML being used then you need to use a MessageContract. I hope you enjoyed reading it!