One of the cooler things about WCF shown at PDC last year was the use of WCF's custom XML stack. In a nutshell, WCF wraps the functionality of existing System.Xml types to allow greater messaging functionality. The types in WCF's xml stack are defined in the System.Runtime.Serialization assembly. Some interesting types in this assembly are System.Xml.XmlDictionary, System.Xml.XmlDictionaryReader, and System.Xml.XmlDictionaryWriter. This post extends part of Doug Purdy's COM326 PDC talk.
 
Consider the following XML content:
<?xml version="1.0" encoding="utf-8"?><Company>Wintellect</Company>
 
Using pre-WCF types we write/read this content to/from a stream using the following code:
 
    // write content to stream using XmlWriter
    MemoryStream stream = new MemoryStream();
    using (XmlWriter writer = XmlWriter.Create(stream))
    {
      writer.WriteElementString("Company", "Wintellect");
      writer.Flush();
      // shows 70 bytes written
      Console.WriteLine("XmlWriter wrote {0} bytes", stream.Position);
      stream.Position = 0;
      Console.WriteLine("data read from stream:\n{0}\n", new StreamReader(stream).ReadToEnd());
    }
 
Writing roughly the equivalent code using the XML Stack in WCF is as follows:
 
    // write content to stream using the text flavor of WCF's XmlDictionaryWriter
    stream = new MemoryStream();
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream, Encoding.UTF8, false))
    {
      writer.WriteStartDocument();
      writer.WriteElementString("Company", "Wintellect");
      writer.Flush();
      // shows 67 bytes written
      Console.WriteLine("XmlDictionaryWriter (Text-UTF8) wrote {0} bytes", stream.Position);
      stream.Position = 0;
      Console.WriteLine("data read from stream:\n{0}\n", new StreamReader(stream).ReadToEnd());
    }
 
From a messaging perspective, what if we wanted to create MTOM encoded XML? Well, we can do the following:
 
    // write content to stream using the MTOM flavor of WCF's XmlDictionaryWriter
    stream = new MemoryStream();
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateMtomWriter(stream, Encoding.UTF8, Int32.MaxValue, "Application/soap+xml"))
    {
      writer.WriteStartDocument();
      writer.WriteElementString("Company", "Wintellect");
      writer.Flush();
      // show that 546 bytes were written
      Console.WriteLine("XmlDictionaryWriter (MTOM-UTF8) wrote {0} bytes", stream.Position);
      stream.Position = 0;
      Console.WriteLine("data read from stream:\n{0}\n", new StreamReader(stream).ReadToEnd());
    }

One of the takeways from the previous example is that MTOM is not always optimal! It is important to remember that MTOM is intended for transporting binary data and allowing signatures to be safely applied to that data (But I digress).
 
You may have seen that WCF fully supports the XmlInfoset. Nowhere is this more apparent than when writing binary XML. Keep in mind that binary XML is still XML, it is just encoded differently. You can write binary XML with the WCF XML stack like the following:
 
    // write content to stream using the binary flavor of WCF's XmlDictionaryWriter
    // without using a dictionary
    stream = new MemoryStream();
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream, null, null))
    {
      writer.WriteStartDocument(); // does nothing in Feb CTP
      writer.WriteElementString("Company", "Wintellect");
      writer.Flush();
      // shows that 21 bytes were written
      Console.WriteLine("XmlDictionaryWriter (Binary, no dictionary) wrote {0} bytes", stream.Position);
      stream.Position = 0;
      XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream);
      reader.Read();
      Console.WriteLine("data read from stream:\n{0}\n", reader.ReadOuterXml());
    }
 
Now to the dictionary part of the XmlDictionaryWriter / XmlDictionaryReader. The WCF XML stack allows XML data to be substitued with other data. In practical terms, this allows you to substitue XML content and "compress" the resultant data. The following code snippet shows how:
 
    // write content to stream using the binary flavor of WCF's XmlDictionaryWriter
    // with a custom dictionary
    stream = new MemoryStream();
    XmlDictionary dictionary = new XmlDictionary();
    XmlDictionaryString entry = dictionary.Add("Company");
 
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream, dictionary, null))
    {
      writer.WriteStartDocument(); // does nothing in FebCTP
      writer.WriteElementString(entry, XmlDictionaryString.Empty, "Wintellect");
      writer.Flush();
   // shows 14 bytes written
      Console.WriteLine("XmlDictionaryWriter (Binary w/dictionary) wrote {0} bytes", stream.Position);
      stream.Position = 0;
      XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, dictionary);
      reader.Read();
      Console.WriteLine("data read from stream:\n{0}\n", reader.ReadOuterXml());
    }
 
In my view, this is way cool. The Project is available here:
 
Dictionaries.zip (14.26 KB)  (NOTE: This sample requires the FebCTP of WCF....)
 
And will produce output like the following: