Home / .NET / NServiceBus embedding raw Xml into messages

NServiceBus embedding raw Xml into messages



This post covers another of the little gems NServiceBus 4.0.0 will have when shipped. In certain scenarios you might require to either send or publish raw Xml data over the wire with messaging. NServiceBus has already the possibility to send or publish messages with large content over the databus. Basically the databus allows to enrich the messages with so called databus properties. Those properties can contain large blobs which are written from the sender or publisher into a commonly agreed folder (often a network share on the SAN storage). What is then transported to the receiver side is only a unique token information which allows the receiver to retrieve the large blob from the shared storage and propagate it again on the message. The databus is especially important when you want to send or publish information which exceeds the message size limitations of the underlying transport mechanism. For example the MSQM transport can only send about 4 megabytes of data. But what if you have small Xml raw data which you want to send or publish with the message without using the databus?

If you try to define a message containing a string property and then add the Xml raw data on that property the Xml data will get escaped on the transport layer. Let us look what happens if we design the following message

public interface MessageWithRawXml {
    string XmlData { get; set; }
}

and add condition codes from world weather online on the XmlData property

<?xml version="1.0" encoding="UTF-8"?>
<codes>
  <condition>
    <code>395</code>
    <description>Moderate or heavy snow in area with thunder</description>
    <day_icon>wsymbol_0012_heavy_snow_showers</day_icon>
    <night_icon>
      wsymbol_0028_heavy_snow_showers_night</night_icon>
    </condition>
</codes>

The sender might look like the following (pretty simplified example):

    public class Server : IWantToRunAtStartup
    {
        public const string Xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<codes>"
+ "  <condition>"
+ "    <code>395</code>"
+ "    <description>Moderate or heavy snow in area with thunder</description>"
+ "    <day_icon>wsymbol_0012_heavy_snow_showers</day_icon>"
+ "    <night_icon>"
+ "      wsymbol_0028_heavy_snow_showers_night</night_icon>"
+ "    </condition>"
+ "</codes>";

        public IBus Bus { get; set; }

        public void Run()
        {
            this.Bus.Send<MessageWithRawXml>(m => m.XmlData = Xml);
        }

        public void Stop()
        {
        }
    }

What happened on the transport layer?

XmlMessageEscaped

The image above shows only an extract of the whole message but we can clearly see that the original Xml data got escaped. But if we want to preserve the original Xml, how can we achieve this?

It is simple. We can declare the property XmlData either as XDocument or XElement and assign the raw Xml to that property. NServiceBus will then take care of properly serializing the XDocument or XElement to the underlying transport. Let us look into the code:

    public interface MessageWithRawXml
    {
        XDocument XmlData { get; set; }
    }

and the sender

this.Bus.Send<MessageWithRawXml>(m => m.XmlData = XDocument.Load(new StringReader(Xml)));

What happened on the transport layer?

XmlMessageNotEscaped

And this works seamlessly over all serializers (Json, Bson, Binary…)! You don’t believe me? Here is the Json variant:

XmlMessageWithJson

But always remember the message size limit of your transport layer. If you need to send large Xml structure you should use the databus! My next post will also cover another feature which was introduced in the serializer area. Have fun with NServiceBus!