ServicesResourcesConferencesOur TeamWeblogsAboutContact
   

Subscriptions

Post Categories

News

    MicrosoftBizTalkBlogs

Affiliations

Archives

Shaping data for the DataContractSerializer (and thus WCF)

The other day we came across this small thing while writing some sample code for our docs.

We can control the way our CLR arrays are serialized in a well-known way by using XmlSerializer and the XmlArrayAttribute and XmlArrayItemAttribute attributes.
For example having a type like this...

[XmlType(TypeName="Family")]
public class Family
{
  [XmlArray(ElementName = "Members")]
  [XmlArrayItem(ElementName = "Name")]
 
public string[] Members;
}

...could produce XML as follows by leveraging XmlSerializer.

<Family xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Members>
    <Name>A</Name>
    <Name>B</Name>
    <Name>C</Name>
    <Name>D</Name>
  </Members>
</Family>

Now, if we define a bare WCF data contract to represent the same family it would look like this:

[DataContract]
class Family
{
  [DataMember]
  public string[] Members;
}

The DataContractSerializer (DCS) produces the following XML for an instance of the Family class:

<Family xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Client">
  <Members xmlns:d2p1="
http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <d2p1:string>A</d2p1:string>
    <d2p1:string>B</d2p1:string>
    <d2p1:string>C</d2p1:string>
    <d2p1:string>D</d2p1:string>
  </Members>
</Family>

But if we want to make it look equivalent to the XML generated for the XmlSerializer-based Family document instance, how could we do that?

There is a solution. Looking at the following screenshot from Lutz's fantastic Reflector we can see there are some attributes we can use to massage the XML spit out by DCS.

WCF's DataContractSerializer attributes

So, instead of using an array, you need to use a collection type marked with the CollectionDataContractAttribute (you can derive a type from an existing collection type and add the attribute). The attribute has properties that can be used to customize array item names, etc.

E.g.:

[DataContract(Name="Family")]
class Family
{
  [DataMember(Name="Members")]
  public MemberList Members;
}

[CollectionDataContract(ItemName="Name")]
class MemberList : List<string> { }


Feel free to download a small demo solution for WinFX Beta 2.


posted on Wednesday, June 21, 2006 10:08 AM

# re: Shaping data for the DataContractSerializer (and thus WCF) @ Wednesday, June 21, 2006 1:26 PM

Humm, is it just me, or does that somehow seems like a step backwards? :)
Tomas Restrepo

# re: Shaping data for the DataContractSerializer (and thus WCF) @ Monday, June 26, 2006 11:51 AM

Hello Christian,

This example looks very interesting but do you know if it is possible to implement a Custom DCS that would serialize this NHibernate class (PersistentCollection) :
http://www.koders.com/csharp/fid371A022994372753EBD5ADDC91CAD300F6217E67.aspx

The idea is to pass (I know this is not recommended in the SOA best practices) a collection of entities (or Proxies) between a WCF service and a remote client.

Thanx.

Sam



Sam

# Collection property serialization with DataContractSerializer == step backwards @ Thursday, September 28, 2006 5:15 PM


hacked.brain

# Collection property serialization with DataContractSerializer takes us a step backwards? @ Thursday, September 28, 2006 5:16 PM


hacked.brain


Powered by Community Server, by Telligent Systems