Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

XML Serializer

NuGet Package: NServiceBus (9.x)

Usage

endpointConfiguration.UseSerialization<XmlSerializer>();

Inferring message type from root node name

In integration scenarios where the sender is unable to add headers to the message, the serializer can infer the message type based on the root node of the XML payload. To take advantage of this, the name of the payload's root node must match the Type.FullName of a message type known to the receiving endpoint.

This technique allows messages without any headers, including the NServiceBus.EnclosedMessageTypes header, to be processed. This is demonstrated by the native integration with RabbitMQ sample.

Raw XML

In certain integration scenarios it may be necessary to bypass NServiceBus's opinionated serialization format (essentially key/value pairs) and directly send custom XML structures over messaging. In order to do that, declare one or more properties on the message contract as XDocument or XElement.

Message with XDocument

public class MessageWithXDocument :
    IMessage
{
    // name and casing must match the rootnode
    public XDocument nutrition { get; set; }
}

Message with XElement

public class MessageWithXElement :
    IMessage
{
    // name and casing must match the rootnode
    public XElement nutrition { get; set; }
}

Payload with raw XML

Using XDocument or XElement message properties will wrap the raw XML data in an outer node named after the property. The node will have the message definitions above and the following XML content:

<nutrition>
    <daily-values>
        <total-fat units='g'>65</total-fat>
        <saturated-fat units='g'>20</saturated-fat>
    </daily-values>
</nutrition>

The full message payload might look like this:

<?xml version="1.0"?>
<MessageWithXDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <nutrition>
        <nutrition>
            <daily-values>
                <total-fat units="g">65</total-fat>
                <saturated-fat units="g">20</saturated-fat>
            </daily-values>
        </nutrition>
    </nutrition>
</MessageWithXDocument>

To avoid the extra node (e.g. for interoperability reasons), instruct the serializer not to wrap raw XML structures:

var serialization = endpointConfiguration.UseSerialization<XmlSerializer>();
serialization.DontWrapRawXml();

This will change the payload as follows:

<?xml version="1.0"?>
<MessageWithXDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <nutrition>
        <daily-values>
            <total-fat units="g">65</total-fat>
            <saturated-fat units="g">20</saturated-fat>
        </daily-values>
    </nutrition>
</MessageWithXDocument>
The name of the property on the message must match the name of the root node in the XML structure exactly in order to be able to correctly deserialize the no longer wrapped content.

Caveats

XML attributes

The XML serializer in NServiceBus is a custom implementation. As such it does not support the standard .NET XML attributes.

Unsupported types

  • HashTable
  • Types with non-default constructors. So types must have a public constructor with no parameters.
  • ArrayList

Samples