Feature Post

Top

WCF: Why use MessageContract when DataContract is there?

Windows Communication Foundation (WCF): Why use MessageContract when DataContract is there?

UPDATED 07/15/2012: Based upon comments
Nutshell: Just know that, data contracts are used to define the data structure. Messages that are simply a .NET typed convenience for generating the XML for the data you want to pass.

Message contracts are preferred only when there is a need to "control" the layout of your message(the SOAP message); for instance, adding specific headers/footer/etc to a message.



Keeping it simple, stupid:
Data contracts are used to define the data structure. Messages that are simply a .NET type, lets say in form of POCO (plain old CLR object), and generate the XML for the data you want to pass.

Message contracts are preferred only when there is a need to "control" the layout of your message(the SOAP message); for instance, adding specific headers/footer/etc to a message.

Detailed answer:
While going through couple of WCF examples, this question was bogging down my empty skull for some time; and when I realized the difference and usage of each in specific scenario, which basically would base upon my requirement, I am posting this for if anyone who is going through the mind-boggles of similar sort!

What is a Contract, really? Wiki says:
"In law, a contract is a binding legal agreement that is enforceable in a court of law.[1] That is to say, a contract is an exchange of promises for the breach of which the law will provide a remedy."


So what does that mean? In technical terms this means that these contracts(DataContract, MessageContract) bounds the IO client with specific terms and conditions; and only when met, the data is exchanged.
MSDN: A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts. A data contract precisely defines, for each parameter or return type, what data is serialized (turned into XML) to be exchanged." - See DataContract types.

1. DataContracts descibes the datatypes used by a service.
2. DataContracts can be used to describe either parameters or return values.
3. DataContracts are unnecessary if the service only uses simple types
4. Data contracts enable interoperability through the XML Schema Definition (XSD) standard.

Note that, this enables the types to be described in metadata to enable the clients to interop with the service.


Following is how a basic DataContract is defined:

[DataContract]
public class Shape { }

[DataContract(Name = "Circle")]
public class CircleType : Shape { }

[DataContract(Name = "Triangle")]
public class TriangleType : Shape { }

While, MessageContract(s) describes the structure of SOAP messages(since SOAP is context oriented - passing-on complete information about object) sent to/from a service and enable you to inspect and control most of the details in the SOAP header and body.

1. Generic - MessageContract enables you to interoperate with any system that communicates through SOAP.
2. Control - Using message contracts, we get complete control over SOAP messages sent to/from a service by having access to the SOAP headers and bodies.
3. Object Context - This(SOAPing) allows use of simple or complex types to define the exact content of the SOAP.

MSDN: sometimes complete control over the structure of a SOAP message is just as important as control over its contents. This is especially true when interoperability is important or to specifically control security issues at the level of the message or message part. In these cases, you can create a message contract that enables you to use a type for a parameter or return value that serializes directly into the precise SOAP message that you need.

Following is a simplest message contract:
[MessageContract]
public class BankingDepositLog
{
  [MessageHeader] public int numRecords
  [MessageHeader] public DepositRecord records[];
  [MessageHeader] public int branchID;
}

And above would result as following in SOAP headers:

3

  Record1
  Record2
  Record3

20643



To see why it is useful to use MessageContract(s), that is, to pass information in SOAP headers, you will have to dive into the SOAP advantages; and yep I am not getting into the disadvantages of SOAP (0: since their aren't too many - and those which are there are vary from scenario to scenario. This obviously does not mean you use SOAP all the time, but you definitely would require a good reason to use SOAP headers over simple XML.

Enjoy coding!