WCF Messaging Fundamentals
Aaron Skonnard has published an article about WCF Messaging Fundamentals in the current issue of the MSDN Magazine. He provides an overview of WCF's messaging layer, improvements in the System.Xml namespace as well as guidance on working with messages and message representations.
The topmost layer of Windows Communication Foundation (WCF aka Indigo) is the Service Layer, which provides a high-level API including Service- and DataContracts, bindings, proxies and dispatcher. Most of the WCF developers will work with the Service Layer, only. Underneath this high-level API WCF offers a full-fledged XML-based messaging layer. By default WCF is based on XML 1.0, SOAP 1.2 and WS-Addressing 1.0 when transmitting messages, but WCF allows to choose from a multitude of alternative settings for configuring almost every aspect of the messaging infrastructure. This flexibility is supported by two key features: variable XML representations and the Message class.
The System.Xml namespace has been extended with the XmlDictionaryReader and the XmlDictionaryWriter. Both classes provide byte representations in addition to the text representation, which is already available in previous framework versions. You may choose between the following representations:
- XML 1.0 text
- MTOM binary (Message Transmission Optimization Mechanismis a W3C Recommendation based on the XML InfoSet and is widely supported)
- Binary (.NET to .NET)
Windows Communication Foundation builds on this by letting you choose which XML representation to use when transmitting messages. If you need interoperability, you should choose the XML 1.0 text representation. If you need interoperability along with efficient support for binary payloads, you should choose the MTOM representation. And in scenarios that are .NET-only, the binary representation may provide better performance. The key here is that you actually have a choice.
The Message class is a representation of an XML message, consisting of a body and optional headers. Although this concept maps directly to a SOAP envelope, WCF also supports other formats than SOAP. The contents of the message are accessible via the XML API provided by the System.Xml namespace, for instance the XmlDictionaryReader und XmlDictionaryWriter mentioned above. The Message class provides several methods for accessing and creating messages:
[...] the Message class essentially models a message body and collections of message headers and properties. The available methods are primarily for creating messages, reading and writing the message body, and manipulating the collections of headers and properties.
The Message Version controls the format of the message when creating messages:
In the case of creating a message from scratch, you must specify the action, the message version, and the body to use within the message. The action uniquely identifies the intent or semantics of the message. Windows Communication Foundation services rely on the action to dispatch incoming messages to the appropriate method. The message version identifies which versions of SOAP and WS-Addressing to use during transmission, if any.
If you want to use a POX (Plain-Old-XML) style of messaging instead of SOAP, you can configure the Message Version accordingly. In his blog entry about "HTTP/POX Programming Basics" Steve Maine shows how POX messaging gets even easier with WCF in Orcas.
In the end Aaron Skonnard describes the lifetime of a message and the different message states:
A Message object starts out in the Created state, which is the only valid state for processing the body. There are a few different ways to process the body: you can read it, write it, or copy it. Calling either GetReaderAtBodyContents or GetBody
changes the state to Read. Calling either WriteMessage or WriteBody changes the state to Written. And calling CreateBufferedCopy changes the state to Copied.
Once a Message object is no longer in the Created state, any method that needs access to the body will throw an exception. For example, calling GetBody
again, after the first call results in an exception. In situations where you need to process the body multiple times, you can create a buffered copy (by calling CreateBufferedCopy) or you can load the body into an XmlDocument or deserialize it into a .NET object for in-memory use.
The article and the accompanying listings clearly show how easy it is to implement pure XML messaging using WCF. Although the messaging approach seems to be the most natural way of developing service-oriented systems, the Service Layer is predominantly used by most WCF developers. On the one hand this might be caused by the fact that Microsoft and most of the MS evangelists recommend this model, on the other hand it might be the result of a lack of good XML messaging sample code and introductory reading.