2010 m. kovo 12 d., penktadienis

Communication between WCF and JBoss server via REST

Part 3: Controlling serialization and prefixed namespaces


In this part I would like to demonstrate how to customize serialization process and to introduce some interoperability issues. Plot is the same: we are communicating with java server and its internal logic requires specifying namespace prefixes:

<ns2:student xmlns:ns2="http://pauliusraila.blogspot.com/">
<id>12</id>
<name> Raila</name>
</ns2:student>


According to the XML specification for namespaces 1.1:  http://www.w3.org/TR/2006/REC-xml-names11-20060816/ there are two ways to specify the namespace: 
  • default namespace attribute
  • prefixed namespace attribute
According to this following message should be interpreted the same as the previous one:

<student xmlns="http://pauliusraila.blogspot.com/">
<id>12</id>
<name> Raila</name>
</student>


Unfortunately we have to use only prefixed namespace attributes.


.NET provided serializers:
  • XmlSerializer 
  • DataContractSerializer
DataContractSerializer is the default in WCF unless you specify that XmlSerialzier should be used. It works with a subset of XML Infoset and therefore provides a better performance and reduces message size.


DataContractSerializer provides a possibility to specify custom namespace but only as the default namespace attribute. 

We have to utilize XmlSerializer.


Although XmlSerializer can be used both in declarative and imperative manner in current situation we have to pass XmlSerializerNamespaces object and we have to utilize an imperative way:

XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("ns", "
http://pauliusraila.blogspot.com");

Moreover we can no longer use HttpContentExtensions libraries to create a serialized content:


HttpContentExtensions.CreateXmlSerializable<Account >(newAccount); 

Instead this I've wrote a generic method which uses a custom namespace object:

 public static HttpContent CreateHttpContent(T obj, XmlSerializerNamespaces namespaces)
{
            XmlSerializer ser = new XmlSerializer(typeof(T));
            MemoryStream ms = new MemoryStream();
           
            namespaces == null ? 

               ser.Serialize(ms, obj): ser.Serialize(ms, obj, namespaces);
            ms.Close();

         
            return HttpContent.Create(ms.ToArray());          
  }