The System.ServiceModel.Channels.Message abstract type is the fundamental unit of communication in the Microsoft Windows Communication Foundation (WCF). Even though the Message type is used in every WCF application, access to it is largely abstracted away from the purview of the application developer. As a result, it is possible to write a feature-rich WCF application without ever directly interacting with an instance of a Message object. However, even if your code does not directly interact with Message objects, keep in mind that the WCF infrastructure is busy behind the scenes, creating, sending, receiving, or otherwise processing Message objects.
Pay careful attention to the notation used in this chapter. When I use Message, I am referring to the System.ServiceModel.Channels.Message type. When I use message, I am referring to the abstract notion of data sent or received.
If the WCF infrastructure takes care of the Message processing for us, why should we spend the time and energy required to understand the Message type? In my opinion, there are two important reasons. First, many common WCF customizations (like behaviors and encoders) require direct interaction with the Message type. If you don’t know anything about the Message type, these customizations will take longer than necessary, and you might do something that has drastic consequences for the rest of the WCF infrastructure. Second, I have found that a solid understanding of the Message type dramatically improves one’s holistic understanding of WCF. On one level, most of the WCF infrastructure assists in the generation, sending, receiving, or other processing of Message objects, and as a direct result, understanding the Message type is fundamental in understanding the inner workings of WCF. For the purposes of enabling you to extend WCF and enhancing your general understanding of WCF, this chapter explains the core functionality of the Message type, as well as several other types that interact with Message objects.
The Message reference type is the WCF abstraction of a SOAP message. As a result of this close association with a SOAP message, the Message type defines members that represent the SOAP version, envelope, header, header blocks, and body elements of a SOAP message. Like all XML-centric WCF types, the Message type is built on an XML Infoset. In effect, the Message type is really just a wrapper around a data store, and that data store is an XML Infoset.
The relationship between the Message type and SOAP messages requires some explanation. When the architects at Microsoft designed WCF, they envisioned XML and SOAP as being the standard structure for all messaging applications. The industry has certainly trended in that direction. Most, if not all, modern messaging platforms have some support for sending and receiving XML messages. Many of these platforms have also embraced SOAP as the primary message structure. With this in mind, the architects at Microsoft drew the logical conclusion that SOAP and XML were the perfect choice for a message structure, and so the Message type fully embraces SOAP and has SOAP semantics baked into the object model.
At first glance, it might appear as though JSON could simply be another encoder that is applied to an instance of a Message, much like the Message Transmission Optimization Mechanism (MTOM). On closer inspection, several problems with this approach become apparent. For starters, JSON has no concept of XML namespaces and attributes. Our mythical JSON encoder would need to strip that information out of the XML. Furthermore, the order of strings is very important in JSON. In XML, the schema defines the order of elements. If a schema does not demand any order in the XML message, translating equivalent XML messages into the same JSON object is difficult, if not impossible. In an effort to solve this problem, the WCF team will release several additional types that assist in Message serialization.
Throughout its lifetime, a Message object must undergo several transformations before it can be transmitted to another messaging participant. From the sender’s perspective, this transformation is a two-step process consisting of serialization and encoding. Message serialization is the act of transforming an instance of a Message into an XML Infoset, and encoding is the act of transforming an XML Infoset into a particular wire format. From the receiver’s perspective, this transformation is the reverse of the one performed by the sender. In other words, the receiver must decode the received data into an Infoset and then deserialize that Infoset into an instance of a Message.
Much of the Message object model is dedicated to Message serialization and deserialization, and most of these members leverage other types in the WCF application programming interface (API). As a result, it is necessary to understand the types responsible for serialization and encoding before examing the Message type. The next section is devoted to examining the foundational types responsible for Message serialization and encoding. After we have looked at these serialization and encoding types, we will resume our examination of the Message type.