XMLDictionary & Serialization in WCF

Posted: December 26, 2009 in WCF

We all are quite conversant with the XmlWriter & XmlReader classes in System.Xml namespace.But not that much with the XmlDictionary ,XmlDictionaryReader & XmlDictionaryWriter present in System.Xml namespace in System.Runtime.Serialization assembly.These are used primarily by the WCF framework to optimize XML serialization/deserialization.In this post we will see how a XML Dictionary can be used to make XML writing/reading more optimized.

A very commonplace way to writing XML data is shown below:

MemoryStream ms = new MemoryStream();
using (XmlWriter wr = XmlWriter.Create(ms))
{
    wr.WriteElementString("Name", "Sankarsan Bose");
} 

//Read & Print
using (StreamReader rr = new StreamReader(ms))
{
    ms.Position = 0;
    Console.WriteLine("Data Size:{0},Data:{1}", ms.Length, rr.ReadToEnd());
} 

Here the output will be

Data Size:68,Data:<?xml version=”1.0″ encoding=”utf-8″?><Name>Sankarsan Bose</Name>

XML Dictionary is used to store the mapping between commonly used string & integer values in the xml and provides a way to compress/decompressing the XML.The two methods provided by the XMLDictionary class are:

  • public virtual XmlDictionaryString Add(string value)
    • This method is used add a string value as Dictionary entry.This method returns an instance of System.Xml.XmlDictionaryString object which represents a dictionary entry.This object exposes the properties Key & Value which returns the dictionary entry’s key & value.
  XmlDictionary dict = new XmlDictionary();
                    XmlDictionaryString dictEntry = dict.Add("Name");
                    Console.WriteLine("Key:{0},Value:{1}",dictEntry.Key , dictEntry.Value);   

                    Here the output is Key:0,Value:Name

  • public virtual bool TryLookup(int key,out XmlDictionaryString result)
    • Looks for a specified dictionary entry by key
  • public virtual bool TryLookup(string value,out XmlDictionaryString result)
    • Looks for a specified dictionary entry by value
  • public virtual bool TryLookup(XmlDictionaryString value,out XmlDictionaryString result)
    • Looks for a specified dictionary entry by value

 

XmlDictionaryString output = XmlDictionaryString.Empty;
          dict.TryLookup(0, out output);
          Console.WriteLine("Key:{0},Value:{1}", dictEntry.Key, dictEntry.Value);  

          Here the output is naturally Key:0,Value:Name

Now this dictionary needs to be used in conjunction with some writer & reader classes which will use this dictionary to compress & decompress the XML.For this purpose we have XmlDictionaryWriter & XmlDictionaryReader classes.These are abstract classes.These classes provides following static methods to create writer/reader as shown below:

  • XmlDictionaryWriter
    • CreateBinaryWriter
    • CreateTextWriter
    • CreateDictionaryWriter
    • CreateMtomWriter
  • XmlDictionaryReader
    • CreateBinaryReader
    • CreateTextReader
    • CreateDictionaryReader
    • CreateMtomReader

Let’s checkout how we can use a XmlDictionary with Binary writer to compress XML data.

XmlDictionary dict = new XmlDictionary();
XmlDictionaryString dictEntry = dict.Add("Name"); 

ms = new MemoryStream();
XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateBinaryWriter(ms, dict);
xdw.WriteElementString(dictEntry, XmlDictionaryString.Empty, "Sankarsan Bose");
xdw.Flush();
using (StreamReader rr = new StreamReader(ms))
{
    ms.Position = 0;
    rr.Read();
    Console.WriteLine("Data Size:{0},Data:{1}", ms.Length,rr.ReadToEnd() );
}
ms.Close(); 

 

Here we have

  1. Added an entry to the XmlDictionary corresponding to the name of the XML element.
  2. We have created a XmlDictionaryWriter by passing that instance of XmlDictionary & MemoryStream.
  3. Written the Xml element to the stream using WriteElementString method of the writer.This method has got the following signature:
    • public void WriteElementString(XmlDictionaryString localName,XmlDictionaryString namespaceUri,string value)
      • Here we have passed the dictionary entry
      • Empty dictionary entry
      • Value of the element node in XML

The output is something like:

Data Size:18,Data: ?♫Sankarsan Bose

Note, the data size has reduced from 68 in case XmlWriter to 18.Obviously this is not a properly readable XML.To do so we need the XmlDictionaryReader as shown below.

ms.Position = 0;
XmlDictionaryReader xr = XmlDictionaryReader.CreateBinaryReader(ms,dict, XmlDictionaryReaderQuotas.Max);
xr.Read();
Console.WriteLine("Data Size:{0},Data:{1}", ms.Length, xr.ReadOuterXml()); 

We have used the following overload of CreateBinaryReader method:

  • public static XmlDictionaryReader CreateBinaryReader(Stream stream,IXmlDictionary dictionary,    XmlDictionaryReaderQuotas quotas
    )
    • Passed the MemoryStream containing Xml data
    • Passed dictionary used to write the xml data
    • The class XmlDictionaryReaderQuotas provides quota values for Xml read operation like maximum node depth,maximum array size etc.Here we have set all the parameters to maximum limit.

Now the output is a proper Xml as desired

Data Size:18,Data:<Name>Sankarsan Bose</Name>

That’s all for now.Oh..here we have used a static XmlDictionary which is used for both writing & reading the data.However dynamic dictionaries are also available where sender can modify the dictionary information and this is sent out of band to the receiver.We can take a look at this later.

About these ads
Comments
  1. XMLDictionary & Serialization in WCF « Sankarsan’s Journal…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. XMLDictionary & Serialization in WCF « Sankarsan’s Journal…

    Thank you for submitting this cool story – Trackback from PimpThisBlog.com…

  3. XMLDictionary & Serialization in WCF…

    Thank you for submitting this cool story – Trackback from Servefault.com…

  4. [...] This post was mentioned on Twitter by Sankarsan Bose, Solidsoft. Solidsoft said: XMLDictionary & Serialization in WCF « Sankarsan's Journal: XMLDictionary & Serialization in WCF. December 26… http://bit.ly/6Gqd7a #WCF [...]

  5. Volen says:

    I’ve seen those examples everywhere. However nobody seems to have an example on how to actually configure WCF to make use of the XmlBinaryWriter plus the dynamic XmlDictionary. Can you post such an example ? Without this example, what good is it to know that XmlBinaryWriter can make a difference ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s