The IBM MQ transport uses standard IBM MQ message structures, making it possible to exchange messages between NServiceBus endpoints and native IBM MQ applications.
Message structure
NServiceBus messages on IBM MQ consist of a standard message descriptor (MQMD) and custom properties stored in MQRFH2 headers.
MQMD fields
The transport maps NServiceBus concepts to the following MQMD fields on send:
| MQMD field | Usage |
|---|---|
| MessageId | Set from the NServiceBus. header. Accepts a GUID or a hex string up to 24 bytes. |
| CorrelationId | Set from the NServiceBus. header. Accepts a GUID or a hex string up to 24 bytes. |
| MessageType | Always MQMT_DATAGRAM |
| Persistence | Persistent by default; non-persistent if NonDurableMessage header is set |
| Expiry | Set from the time-to-be-received setting; unlimited if not specified |
| ReplyToQueueName | Set from the NServiceBus. header |
NServiceBus headers
All NServiceBus headers are stored as MQRFH2 message properties. Property names are escaped because IBM MQ only allows alphanumeric characters and underscores in property names. The escaping rules are:
- Underscores are doubled:
_becomes__ - Other special characters are encoded as
_xHHHH(e.g.,.becomes_x002E)
IBM MQ silently discards string properties with empty values. To preserve all header names and maintain empty values, the transport uses manifest properties: nsbhdrs (lists all header names) and nsbempty (tracks empty-valued headers). The header fields with non-compliant names will now be displayed in the IBMMQ Console.
Receiving from non-NServiceBus senders
When a message arrives from a native IBM MQ application that does not set MQRFH2 properties, the transport promotes the following MQMD fields to NServiceBus headers. Promotion only occurs if the corresponding NServiceBus header is not already set. This ensures NServiceBus-originated messages are not overwritten.
| MQMD field | NServiceBus header | Notes |
|---|---|---|
MessageId | NServiceBus. | Encoded as an uppercase hex string |
CorrelationId | NServiceBus. | Encoded as an uppercase hex string |
ReplyToQueueName | NServiceBus. | Trimmed of whitespace; ignored if empty |
Persistence | NServiceBus. | Set to True when persistence is NOT_PERSISTENT |
Expiry | NServiceBus. | Converted from tenths of seconds; ignored when unlimited |
This enables native senders to rely on standard MQMD fields for identity and routing without requiring knowledge of the NServiceBus header format.
Sending messages from native applications
To send a message to an NServiceBus endpoint from a native IBM MQ application:
- Put a message on the endpoint's input queue.
- Set the message body to your serialized content (e.g., JSON). NServiceBus will deserialize it based on the
ContentTypeproperty you set. - Set the following MQRFH2 properties as a minimum:
| Property name | Description |
|---|---|
NServiceBus_x002EEnclosedMessageTypes | The fully qualified .NET type name of the message |
NServiceBus_x002EContentType | The MIME type of the body (e.g., application/) |
NServiceBus_x002EMessageId | A unique identifier (typically a GUID) |
If the EnclosedMessageTypes header is missing, the endpoint will not be able to deserialize and route the message.
Receiving messages in native applications
Native applications can consume messages from queues that NServiceBus publishes or sends to. The message body contains the serialized payload, and NServiceBus headers are available as MQRFH2 properties.
To read NServiceBus headers from received messages:
- Use the
nsbhdrsmanifest property to enumerate all header names. - For each header name, unescape the property name by:
- Replacing
__with_ - Replacing
_xHHHHwith the corresponding character (e.g.,_x002Ebecomes.)
- Replacing