With WCF you can control many aspects of how service behave and how you interact with them.  Let’s take a look at Data & Message Contracts and how each behaves on the wire.

Data Contracts – The Basics

Data contracts are the default method for serializing in WCF.  To leverage data contracts you simply markup the classes you wish to expose from the service with the DataContractAttribute.  The data contract serializer does not support all the features of Xml Serialization which yields some performance boosts.  However, the data contract serializer has some default behaviors which may not suit your needs.

The Contract

 [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

The SOAP Message

Request (Showing soap:body only)

<s:Body>
<GetDataUsingDataContract xmlns="http://tempuri.org/">
<composite xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service!</a:StringValue>
</composite>
</GetDataUsingDataContract>
</s:Body>

Response

<s:Body>
<GetDataUsingDataContractResponse xmlns="http://tempuri.org/">
<GetDataUsingDataContractResult xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service!Suffix</a:StringValue>
</GetDataUsingDataContractResult>
</GetDataUsingDataContractResponse>
</s:Body>

With the data contract, notice how our messages are actually wrapped in an outer element in the Xml.  For the request, the CompositeType is wrapped in a “GetDataUsingDataContract” element which is derived from the operation name.  The response is where it is interesting, our message is actually double wrapped. 

How do we change this default behavior?  Enter Message Contracts.

Message Contracts – For Control Freaks

Message contracts are another way to work with WCF to take more control of how the messages are serialized in the SOAP envelope.  These can be a key strategy to creating services that can support better interoperability with other stacks such as Java.  You define message contracts with the MessageContractAttribute.

The Message Contract

     [MessageContract(IsWrapped=true, WrapperNamespace=http://christopherDeweese.com/WCF/Examples)]
    public class CompositeTypeRequest
    {
        [MessageBodyMember]
        public CompositeType CompositeData { get; set; }
    }

    [MessageContract(IsWrapped=true, WrapperNamespace=http://christopherDeweese.com/WCF/Examples)]
    public class CompositeTypeResponse
    {
        [MessageBodyMember]
        public CompositeType CompositeData { get; set; }
    }

Here we have defined a request and a response message which contains our CompositeType.  What result does this yield?

The SOAP Message

Request

<s:Body>
<CompositeTypeRequest xmlns="http://christopherDeweese.com/WCF/Examples">
<CompositeData xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service with messages! </a:StringValue>
</CompositeData>
</CompositeTypeRequest>
</s:Body>

Response

<s:Body>
<CompositeTypeResponse xmlns="http://christopherDeweese.com/WCF/Examples">
<CompositeData xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service with messages! Suffix</a:StringValue>
</CompositeData>
</CompositeTypeResponse>
</s:Body>

A Little ‘Philosophy’

In past posts on services I’ve discussed the opinion that you interact with services through messages.  Encapsulating inputs and outputs to the service using messages allows for a clearer semantic representation of the what the capabilities the service provides access to.

Using Message contracts in WCF lets you explicitly control how the messages are serialized and allows you to build services from canonical data models created in raw Xml.  This also provides the greatest interoperability and you don’t have to deal with the default behaviors of the data contract serializer.

Final Thought

You may not always need this type of control.  For instance if your service is only being consumed by other .NET clients the messages may not be that important to you.  But if you are designing services for an Enterprise SOA, then message contracts will be a great help.