Posts tagged Serialization

Take Control of Messages in WCF

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.

WSCF.Blue Support For WCF and a Few Tips on WCF + XmlSerializer

Over a week ago the Web Services Contract First (WSCF) project announced the "blue" version which supports WCF.  WSCF is a great tool that saved my butt on a large integration project with one of our fine 3-letter agencies a few years back.  The tool boasts the ability to take a WSDL and Schema files and turn them into C# or VB code.  When I saw the new release I had to give it a try.

My first run went smooth but I noted the WSCF tool generated the service contract interface type without the "I" prefix.  I reported this to the team and they promptly fixed it and even tried it against the DOJ LEXS WSDLs that I was working on.  Many thanks to Christian Weyer and Alex Meyer-Gleaves for responding so quickly.

In the government data sharing space there is a lot of contract first development happening.  The NIEM IEPD process encourages developing both the business need and data schemas before you begin coding the exchange.  I think this is a great approach to take and helps everyone from the business analysts to the technical analysts understand the exchange, the data to be exchanged, and the overall process. 

Having an open source tool like WSCF is a great addition to your toolbox when interop is key.

As I migrated a soon-to-be-released open source project to it’s new solution I used WSCF to generate all the classes and service stub.  The following are some tips I have when you are using WCF + XmlSerializer; these really have nothing to do with WSCF, you will get the same if you use SvcUtil directly.  That said I think WSCF generates the classes from the schemas with a lot less effort and actually better than Svcutil directly.

Tips for WCF + XmlSerializer

Tip 1: For types that are marked with a MessageContractAttribute and IsWrapped=True, if you inherit from a base class that exposes a public XmlSerializerNamespaces property the namespaces are not properly serialized.  XmlSerializerNamespaces are used when you want to control the namespace prefixing and output during serialization.  This is accomplished by creating a public field with the name "xmlns" and marking it up with the XmlNamespaceDeclarationAttribute.  The XmlSerializer uses the presence of this field to output the Xml Namespaces and the associated prefixes within the element from the object in the object graph where the attribute was applied.

Tip 2: If you have a class marked with the MessageContractAttribute and you inherit from a base class within that class then the base class must also be marked with the MessageContract attribute.  WCF gives you a nice error message explaining this because it is unable to start the service.

Tip 3: In some cases both SvcUtil and WSCF generate ReplyAction="*" on the WSDL.  This could potentially make it fail in an interop scenario.  Not exactly sure what causes that but in any case, if you have trouble then remove that from the service contract.  A tell tale sign is that when you view the WSDL page for your service you do not see any of the operations listed.