Controlling the serialized order of WCF Data Contract Members

April 12, 2008 at 1:08 am | Posted in WCF | Leave a comment

There are situations where you wish to specify the order of fields when they are serialized. I believe that a good designed service should not specify the ordering of fields nor should a service consuming application expect it..

In some applications, it is useful to know the order in which data from the various data members is sent or is expected to be received (such as the order in which data appears in the serialized XML). Sometimes it may be necessary to change this order…..

Recently, I started using ReSharper (now I’m hooked). I used it to reformat my code based on a style which alphabetically reordered all the properties in the data contracts. The changes were checked in, unit tested, integrated united tested and deployed to Test. The changes I made broke the client application as the application was relying on the serialised Xml to be in a certain order. In my opinion this is definately not service design.

I was told about the DataMemberAttribute.Order property by Rory and reluctantly added the Order property to every data contract member. This change still broke the client application. The reason was that the client application was using the XmlSerializer which does not change its behvaior with the new DataMember attributes.

The solution was to serialise a Data Contract using the DataContractSerializer. I still consider this to be a dirty solution because the ordering of the properties must always be the same, otherwise the consumer may break.

Data Contract

The following data contract lists fields in alphabetical order. The Order attribute forces the DataContractSerializer to output elements in the requested order.

    [DataContract]

    public class Person

    {

        [DataMember(Order = 2)]

        public Int32 Age { get; set; }

 

        [DataMember(Order = 0)]

        public String FirstName { get; set; }

 

        [DataMember(Order = 1)]

        public String LastName { get; set; }

 

    }

 

Serializing using the XmlSerializer

    Person person = new Person { Age = 25, FirstName = “Bob”, LastName = “Jane” };

    using (FileStream writer = new FileStream(“Person.xml”, FileMode.Create))

    {

        XmlSerializer xmlSerializer = new XmlSerializer(typeof(Person));

        xmlSerializer.Serialize(writer, person);

        writer.Close();

    }

The XML is written in the order the fields are defined in the class.

  <?xml version=1.0?>

  <Person xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance

          xmlns:xsd=http://www.w3.org/2001/XMLSchema>

    <Age>25</Age>

    <LastName>Jane</LastName>

    <FirstName>Bob</FirstName>

  </Person> 

Serializing using the DataContractSerializer

    Person person = new Person { Age = 25, FirstName = “Bob”, LastName = “Jane” };

    using (FileStream writer = new FileStream(“Person.xml”, FileMode.Create))

    {

        DataContractSerializer contractSerializer = new DataContractSerializer(typeof (Person));

        contractSerializer.WriteObject(writer, person);

        writer.Close();

    }

 

The XML is written in the expected order defined by the Order property, even though the data contract defines in another order.

  <Person xmlns=http://schemas.datacontract.org/2004/07/Wcf.Demo.ServiceContracts

          xmlns:i=http://www.w3.org/2001/XMLSchema-instance>

    <FirstName>Bob</FirstName>

    <LastName>Jane</LastName>

    <Age>25</Age>

  </Person>

 

So if you require a specific order to be xml serialized, make sure you use the DataContractSerializer.

Leave a Comment »

RSS feed for comments on this post. TrackBack URI

Leave a comment

Create a free website or blog at WordPress.com.
Entries and comments feeds.