﻿# Multiple Deserializers


This sample uses the `AddDeserializer` API to illustrate a receiving endpoint deserializing multiple serialization formats.

## Sending endpoints

There are multiple sending endpoints, one per serializer.

### NewtonsoftJsonEndpoint

Sends messages using the external [Json.NET serializer](/nservicebus/serialization/newtonsoft.md) in JSON format.

<!-- snippet: configExternalNewtonsoftJson -->

```cs
var endpointConfiguration = new EndpointConfiguration("Samples.MultipleDeserializers.ExternalNewtonsoftJsonEndpoint");
var serialization = endpointConfiguration.UseSerialization<NewtonsoftJsonSerializer>();
serialization.ContentTypeKey("NewtonsoftJson");
endpointConfiguration.RegisterOutgoingMessageLogger();
```

<!-- endsnippet -->

### NewtonsoftBsonEndpoint

Sends messages using the external [Json.NET serializer](/nservicebus/serialization/newtonsoft.md) in BSON format.

<!-- snippet: configExternalNewtonsoftBson -->

```cs
var endpointConfiguration = new EndpointConfiguration("Samples.MultipleDeserializers.ExternalNewtonsoftBsonEndpoint");

var serialization = endpointConfiguration.UseSerialization<NewtonsoftJsonSerializer>();

serialization.ReaderCreator(stream => new BsonDataReader(stream));
serialization.WriterCreator(stream => new BsonDataWriter(stream));
serialization.ContentTypeKey("NewtonsoftBson");

endpointConfiguration.RegisterOutgoingMessageLogger();
```

<!-- endsnippet -->

### XmlEndpoint

Sends messages using the [XML serializer](/nservicebus/serialization/xml.md).

<!-- snippet: configXml -->

```cs
var endpointConfiguration = new EndpointConfiguration("Samples.MultipleDeserializers.XmlEndpoint");
endpointConfiguration.UseSerialization<XmlSerializer>();
endpointConfiguration.RegisterOutgoingMessageLogger();
```

<!-- endsnippet -->

### SystemJsonEndpoint

Sends messages using [System.Text.Json](/nservicebus/serialization/system-json.md) in JSON format.

<!-- snippet: configSystemJson -->

```cs
var endpointConfiguration = new EndpointConfiguration("Samples.MultipleDeserializers.SystemJsonEndpoint");

endpointConfiguration.UseSerialization<SystemJsonSerializer>();

endpointConfiguration.RegisterOutgoingMessageLogger();
```

<!-- endsnippet -->


## Shared

Contains message definitions and a [message mutator](/nservicebus/pipeline/message-mutators.md) that logs the outgoing data. The project is shared by all endpoints and configured by `endpointConfiguration.RegisterOutgoingMessageLogger();` in the above snippets.

<!-- snippet: outgoingmutator -->

```cs
class OutgoingMessageBodyWriter :
    IMutateOutgoingTransportMessages
{
    static ILog log = LogManager.GetLogger<OutgoingMessageBodyWriter>();

    public Task MutateOutgoing(MutateOutgoingTransportMessageContext context)
    {
        var bodyAsString = Encoding.UTF8
            .GetString(context.OutgoingBody.ToArray());
        log.Info($"Serialized Message Body:\r\n{bodyAsString}");
        return Task.CompletedTask;
    }
}

public static class OutgoingMessageBodyWriterHelper
{
    public static void RegisterOutgoingMessageLogger(this EndpointConfiguration endpointConfiguration)
    {
        // Register the mutator so the message on the wire is written
        endpointConfiguration.RegisterMessageMutator(new OutgoingMessageBodyWriter());
    }
}
```

<!-- endsnippet -->

## ReceivingEndpoint

The receiving endpoint references all the serializers used above and adds them using `AddDeserializer`

<!-- snippet: configAll -->

```cs
var endpointConfiguration = new EndpointConfiguration("Samples.MultipleDeserializers.ReceivingEndpoint");

// Xml
endpointConfiguration.UseSerialization<XmlSerializer>();

// Json
endpointConfiguration.AddDeserializer<SystemJsonSerializer>();

// External Newtonsoft Json
var externalNewtonsoftJson = endpointConfiguration.AddDeserializer<NewtonsoftJsonSerializer>();
externalNewtonsoftJson.ContentTypeKey("NewtonsoftJson");

// External Newtonsoft Bson
var externalNewtonsoftBson = endpointConfiguration.AddDeserializer<NewtonsoftJsonSerializer>();
externalNewtonsoftBson.ReaderCreator(stream => new BsonDataReader(stream));
externalNewtonsoftBson.WriterCreator(stream => new BsonDataWriter(stream));
externalNewtonsoftBson.ContentTypeKey("NewtonsoftBson");

// Register the mutator so the message on the wire is written
builder.Services.AddSingleton<IncomingMessageBodyWriter>();

var serviceProvider = builder.Services.BuildServiceProvider();
var incomingMessageBodyWriter = serviceProvider.GetRequiredService<IncomingMessageBodyWriter>();
endpointConfiguration.RegisterMessageMutator(incomingMessageBodyWriter);
```

<!-- endsnippet -->

There is also a [message mutator](/nservicebus/pipeline/message-mutators.md) that logs the incoming data.

<!-- snippet: incomingmutator -->

```cs
public class IncomingMessageBodyWriter(ILogger<IncomingMessageBodyWriter> logger) :
    IMutateIncomingTransportMessages, IIncomingMessageBodyWriter
{
    public Task MutateIncoming(MutateIncomingTransportMessageContext context)
    {
        var bodyAsString = Encoding.UTF8
            .GetString(context.Body.ToArray());
        var contentType = context.Headers[Headers.ContentType];

        logger.LogInformation("ContentType '{ContentType}'. Serialized Message Body:\r\n{Body}", contentType, bodyAsString);
        return Task.CompletedTask;
    }
}
```

<!-- endsnippet -->
