Message Serialization

MassTransit uses types for messages. Serializers are used convert those types into their respective format (such as JSON, XML, BSON, etc.), which is sent to the message broker. A corresponding deserializer is then used to convert the serialized format back into a type.

By default, MassTransit uses System.Text.Json to serialize and deserialize messages using JSON.

Supported Serializers

MassTransit include support for several commonly used serialization packages.

System.Text.Json

System.Text.Json is the default message serializer/deserializer.

Content TypeFormatConfiguration Method
application/vnd.masstransit+jsonJSON (w/envelope)UseJsonSerializer (default)
application/jsonJSONUseRawJsonSerializer

Customize the Serializer Support

services.AddMassTransit(cfg =>
{
    cfg.Using[Broker](broker => 
    {
        broker.ConfigureJsonSerializerOptions(options =>
        {
            // customize the JsonSerializerOptions here
            return options;
        });
    })
    
})

Newtonsoft

The MassTransit.Newtonsoft package adds the serialization formats listed below.

In MassTransit versions before v8, Newtonsoft was the default message serializer/deserializer.

Content TypeFormatConfiguration Method
application/vnd.masstransit+jsonJSON (w/envelope)UseNewtonsoftJsonSerializer
application/jsonJSONUseNewtonsoftRawJsonSerializer
application/vnd.masstransit+bsonBSON (w/envelope)UseBsonSerializer
application/vnd.masstransit+xmlXML (w/envelope)UseXmlSerializer
application/xmlXMLUseRawXmlSerializer
application/vnd.masstransit+aesBinary (w/envelope)UseEncryptedSerializer
application/vnd.masstransit.v2+aesBinary (w/envelope)UseEncryptedSerializerV2

MessagePack

The MassTransit.MessagePack package adds the serialization formats listed below.

Content TypeFormatConfiguration Method
application/vnd.masstransit+msgpackMessagePack (w/envelope)UseMessagePackSerializer

Message Types

MassTransit stores the supported .NET types for a message as an array of URNs, which include the namespace and name of the message type. All interfaces and superclasses of the message type are included. The namespace and name are formatted as shown below.

urn:message:Namespace:TypeName

A few examples of valid message types:

urn:message:MyProject.Messages:UpdateAccount
urn:message:MyProject.Messages.Events:AccountUpdated
urn:message:MyProject:ChangeAccount
urn:message:MyProject.AccountService:MyService+AccountUpdatedEvent

The last one is a nested class, as indicated by the '+' symbol.

MessageUrn Attribute

MessageUrn is an optional attribute that may be specified on a message type to provide a custom Urn that will be used when the message is published or consumed. The generated Urn will be prefixed with urn:messages: by default, however a full Urn may be provided by specifying useDefaultPrefix: false in the attribute declaration.

[MessageUrn("publish-command")]
public record PublishCommand
{
    // Will generate a urn of: urn:messages:publish-command
}
[MessageUrn("scheme:publish-command", useDefaultPrefix: false)]
public record PublishCommand
{
    // Will generate a urn of: scheme:publish-command
}

Message Envelope

To interoperate with other languages and platforms, message structure is important. MassTransit encapsulates messages in an envelope before they are serialized. An example JSON message envelope is shown below.

{
    "messageId": "181c0000-6393-3630-36a4-08daf4e7c6da",
    "requestId": "ef375b18-69ee-4a9e-b5ec-44ee1177a27e",
    "correlationId": null,
    "conversationId": null,
    "initiatorId": null,
    "sourceAddress": "rabbitmq://localhost/source",
    "destinationAddress": "rabbitmq://localhost/destination",
    "responseAddress": "rabbitmq://localhost/response",
    "faultAddress": "rabbitmq://localhost/fault",
    "messageType": [
        "urn:message:Company.Project:SubmitOrder"
    ],
    "message": {
        "orderId": "181c0000-6393-3630-36a4-08daf4e7c6da",
        "timestamp": "2023-01-12T21:55:53.714Z"
    },
    "expirationTime": null,
    "sentTime": "2023-01-12T21:55:53.715882Z",
    "headers": {
        "Application-Header": "SomeValue"
    },
    "host": {
        "machineName": "MyComputer",
        "processName": "dotnet",
        "processId": 427,
        "assembly": "TestProject",
        "assemblyVersion": "2.11.1.93",
        "frameworkVersion": "6.0.7",
        "massTransitVersion": "8.0.10.0",
        "operatingSystemVersion": "Unix 12.6.2"
    }
}
PropertyTypeNotesSet
messageIdGuidRecommendedY
correlationIdGuidOptional
requestIdGuidSituationalR
initiatorIdGuidOptional
conversationIdGuidOptionalY
sourceAddressUriOptionalY
destinationAddressUriOptionalY
responseAddressUriSituationalR
faultAddressUriOptional
expirationTimeISO-8601SituationalS
sentTimeISO-8601OptionalY
messageTypeUrn[]RequiredY

Set indicates whether the property is automatically set by MassTransit when producing messages. Yes, Requests only, or Situational.

Raw JSON

Consuming messages from other systems where messages may not be produced by MassTransit, raw JSON is commonly used.

When using a serializer that doesn't wrap the message in an envelope (application/json), the above message would be reduced to the raw JSON shown below.

{
    "orderId": "181c0000-6393-3630-36a4-08daf4e7c6da",
    "timestamp": "2023-01-12T21:55:53.714Z"
}

Learn more about using raw JSON messages in this video.

Options

MassTransit provides several options when dealing with raw JSON messages. The options can be specified on the UseRawJsonSerializer method.RawSerializerOptions includes the following flags:

OptionValueDefaultNotes
AnyMessageType1YMessages will match any consumed message type
AddTransportHeaders2YMassTransit will add the above headers to outbound messages
CopyHeaders4NReceived message headers will be copied to outbound messages

In cases where MassTransit is used and raw JSON messages are preferred, the non-default options are recommended.

cfg.UseRawJsonSerializer(RawSerializerOptions.AddTransportHeaders | RawSerializerOptions.CopyHeaders);

Headers

When the RawSerializerOptions.AddTransportHeaders option is specified, the following transport headers will be set (if not empty or default).

Header NameTypeNotes
MessageIdGuid
CorrelationIdGuid
RequestIdGuid
MT-InitiatorIdGuid
ConversationIdGuid
MT-Source-AddressUri
MT-Response-AddressUri
MT-Fault-AddressUri
MT-MessageTypeUrn[]Multiple message types separated by ;
MT-Host-InfostringJSON serialized host info
MT-OriginalMessageIdGuidFor redelivered messages with a newly generated MessageId

Configuration

Serialization customizations for using raw JSON is generally recommended on individual receive endpoints only, vs being globally configured at the bus level.

To configure a receive endpoint so that it can receive raw JSON messages, specify the default content type and add the deserializer as shown below. When a raw JSON message is received, it will be delivered to every consumer configured on the receive endpoint.

endpointConfigurator.DefaultContentType = new ContentType("application/json");
endpointConfigurator.UseRawJsonDeserializer();

If messages produced by consumers on the receive endpoint should also be in the raw JSON format, UseRawJsonSerializer() may be used instead.

Setting the default content type tells MassTransit to use the raw JSON deserializer for messages that do not have a recognized Content-Type header.

To prevent MassTransit from creating exchanges or topics for the message types consumed on the endpoint, disable consume topology configuration.

endpointConfigurator.ConfigureConsumeTopology = false;