blogs.conchango.com

welcome to the conchango blogging site
Welcome to blogs.conchango.com Sign in | Join | Help
in Search

Simon Evans' Blog

My blog covers the technology areas I focus on here at Conchango, namely Architecture using the .Net Framework, ASP.net 2.0, WCF and Agile development practices.

WCF serialization with MSMQ

By default, Windows Communication Foundation (WCF) uses the DataContractSerializer to serialize and deserialize XML in a service, but this serialization mechanism can be replaced to use the XmlSerializer. The following article on MSDN covers this in more detail:

http://msdn2.microsoft.com/en-us/library/ms733901.aspx

Whilst using the Data Contract attributes is much easier, and many more types are supported for serialization, there are various scenarios where switching to the XmlSerializer can be beneficial, such as:

  • Migrating services from ASMX services
  • Tighter control over XML serialization
  • Using WCF with MsmqIntegrationBinding

The latter of these three examples is core reason why I have spent a lot of time investigating the use of serializers within WCF. Msmq integration binding relies upon the old Msmq API's used by the System.Messaging namespace in order to ensure interoperability with other legacy Msmq endpoints, such as BizTalk Server 2006 (pre R2).

The scenario I have been working with is that I want to use MsmqIntegrationBinding with BizTalk Server 2006 in the short term, and move to BizTalk Server 2006 R2 and NetMsmqBinding in the future. Thus in the future I want to move towards using the DataContractSerializer, but in the short term, I need to support the old XmlSerializer, because MsmqIntegrationBinding uses this serialization method internally.

Getting MsmqIntegrationBinding to work with complex data contracts

I have seen dozens of samples on the internet for using MsmqIntegrationBinding in WCF, and in short the basic mechanics are as follows:

  • Create a service contract with a one way service operation that takes a single argument MsmqMessage<T>, where T is a data contract.
  • Ensure the T of MsmqMessage<T> is specified using the ServiceKnownType attribute.

The problem is, all the examples I have seen use a single simple data contract to demonstrate this binding. When a more complex data contract is used, things get more difficult. For example if I have two data contracts A and B, and A exposes B as a data member, the above instructions alone do not work; the message is never received by the service implementation. The reason this would not work is because data contract B is not known to the serializer and thus A could not be serialized.

After much hunting, I found the solution was to implement serialization using the old XmlSerializer, using XmlRoot and XmlArray attributes to decorate each data contract. By using the XmlSerializerFormatAttribute, you don't need to use the data contract attributes at all, as WCF will use the old serializer instead throughout the service contract.

Comparing the DataContractSerializer with the XmlSerializer

In order to ensure a smooth transition from MsmqIntegrationBinding to NetMsmqIntegration binding I have opted to support both serializers in my data contracts, with a view to retiring the XmlSerializer as some point in the future. The problem is, the serializers handle things in different ways. The table below lists the differences:

DataContractSerializer

XmlSerializer

Resolution to serialization differences

If ordering is not specified, the data members are serialized in alphabetical order

The properties are serialized in the order they appear in the class

Ensure the order argument is specified in the data member attribute in the order that the properties appear in the class.

If the data contract contains an array of objects from a different XML namespace, the serialization will automatically set the namespace of the array to be that of the objects within the array.

The namespace of the array will be that of the outer data contract.

Ensure the XmlArray attribute is used against the array property to ensure that the array is serialized the same in both serializers.

Additionally, you must ensure the XSD namespace for each DataContractAttribute and XmlRootAttribute match.

You can compare how the two serialization models match by running svcutil.exe and xsd.exe against the data contract assembly and look at the output XSD schemas.

Published 14 May 2007 17:03 by simon.evans

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

john.rayner said:

The NetDataContractSerializer may also be an option for you - it serializes type as well as contract.  Aaron Skonnard published a good post at http://pluralsight.com/blogs/aaron/archive/2006/04/21/22284.aspx around what it is and how to use it.

May 14, 2007 17:19
 

Travis Spencer said:

What if you specify both data contracts A and B (from your example above) using the KnownType attribute?

January 1, 2008 21:40
 

Niks said:

hii, i like the article you wrote. i also wrote an article on Serialization here : http://kaniks.blogspot.com

feel free to post your comments

thanks

cheers

October 6, 2008 14:10

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Personal Edition), by Telligent Systems