diff --git a/Snippets/ASQ/ASQN_13/CustomEnvelopeUnwrapper.cs b/Snippets/ASQ/ASQN_13/CustomEnvelopeUnwrapper.cs index 25917545803..b46fa881b3d 100644 --- a/Snippets/ASQ/ASQN_13/CustomEnvelopeUnwrapper.cs +++ b/Snippets/ASQ/ASQN_13/CustomEnvelopeUnwrapper.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text.Json; +using System.Buffers.Text; using NServiceBus; using NServiceBus.Azure.Transports.WindowsAzureStorageQueues; @@ -15,23 +13,18 @@ class CustomEnvelopeUnwrapper { MessageUnwrapper = queueMessage => { - var messageText = Convert.FromBase64String(queueMessage.MessageText); - - //try deserialize to a NServiceBus envelope first - var wrapper = JsonSerializer.Deserialize(messageText); - - if (wrapper?.Id != null) - { - //this was a envelope message - return wrapper; - } - + //This sample expects the native message to be serialized only, + // conforming to the specified endpoint serializer. + //NServiceBus messages will always be Base64 encoded, so any messages + // of this type can be forwarded to the framework by returning null. + return Base64.IsValid(queueMessage.MessageText) + ? null //this was a native message just return the body as is with no headers - return new MessageWrapper + : new MessageWrapper { Id = queueMessage.MessageId, - Headers = new Dictionary(), - Body = messageText + Headers = [], + Body = queueMessage.Body.ToArray() }; } }; diff --git a/samples/azure/native-integration-asq/ASQN_13/Receiver/Program.cs b/samples/azure/native-integration-asq/ASQN_13/Receiver/Program.cs index af7ef6a3dc2..478e742aa14 100644 --- a/samples/azure/native-integration-asq/ASQN_13/Receiver/Program.cs +++ b/samples/azure/native-integration-asq/ASQN_13/Receiver/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers.Text; using System.Collections.Generic; using NServiceBus; @@ -18,15 +19,18 @@ #region Native-message-mapping -transport.MessageUnwrapper = message => new MessageWrapper -{ - Id = message.MessageId, - Body = message.Body.ToArray(), - Headers = new Dictionary - { - { Headers.EnclosedMessageTypes, typeof(NativeMessage).FullName } - } -}; +transport.MessageUnwrapper = message => + Base64.IsValid(message.MessageText) + ? null // not a raw native message - allow the framework to deal with it + : new MessageWrapper + { + Id = message.MessageId, + Body = message.Body.ToArray(), + Headers = new Dictionary + { + { Headers.EnclosedMessageTypes, typeof(NativeMessage).FullName } + } + }; #endregion diff --git a/transports/azure-storage-queues/native-integration_sending_asqn_[13,).partial.md b/transports/azure-storage-queues/native-integration_sending_asqn_[13,).partial.md new file mode 100644 index 00000000000..eb7185bc645 --- /dev/null +++ b/transports/azure-storage-queues/native-integration_sending_asqn_[13,).partial.md @@ -0,0 +1,15 @@ +### Custom envelope unwrapper + +Azure Storage Queues lacks native header support. NServiceBus solves this by wrapping headers and message body in a custom envelope structure. This envelope is serialized using the configured [serializer](/nservicebus/serialization) for the endpoint before being sent. + +Creating this envelope can cause unnecessary complexity if headers are not needed, as is the case in native integration scenarios. For this reason, NServiceBus.Transport.AzureStorageQueues 9.0 and above support configuring a custom envelope unwrapper. + +> [!WARNING] +> In this scenario, NServiceBus may place messages in your queue in addition to the native messages that are expected, for example if a message results in a [delayed retry](delayed-delivery.md). Any custom envelope unwrapper must verify if the incoming message is capable of being deserialized as a native message, and the resulting body must be serialized according to the configured endpoint serializer. If either of these conditions cannot be met then `MessageUnwrapper` should return `null` to allow the default unwrapper to handle the message. + +The snippet below shows custom unwrapping logic that enables both NServiceBus formatted and plain serialized messages to be consumed. + +snippet: CustomEnvelopeUnwrapper + +> [!NOTE] +> This feature is currently NOT compatible with ServiceControl. A [ServiceControl transport adapter](/servicecontrol/transport-adapter.md) is required to leverage both. diff --git a/transports/azure-storage-queues/native-integration_sending_asqn_[9,).partial.md b/transports/azure-storage-queues/native-integration_sending_asqn_[9,).partial.md deleted file mode 100644 index fab8437c2b8..00000000000 --- a/transports/azure-storage-queues/native-integration_sending_asqn_[9,).partial.md +++ /dev/null @@ -1,12 +0,0 @@ -### Custom envelope wrapper - -Azure Storage Queues lacks native header support. NServiceBus solves this by wrapping headers and message body in a custom envelope structure. This envelope is serialized using the configured [serializer](/nservicebus/serialization) for the endpoint before being sent. - -Creating this envelope can cause unnecessary complexity if headers are not needed, for example, in native integration scenarios. For this reason, NServiceBus.Transport.AzureStorageQueues 9.0 and above support configuring a custom envelope unwrapper. - -The snippet below shows custom unwrapping logic that enables both NServiceBus formatted and plain JSON messages to be consumed. - -snippet: CustomEnvelopeUnwrapper - -> [!NOTE] -> This feature is currently NOT compatible with ServiceControl. A [ServiceControl transport adapter](/servicecontrol/transport-adapter.md) is required to leverage both. diff --git a/transports/azure-storage-queues/native-integration_sending_asqn_[9,12].partial.md b/transports/azure-storage-queues/native-integration_sending_asqn_[9,12].partial.md new file mode 100644 index 00000000000..01d5edcc30b --- /dev/null +++ b/transports/azure-storage-queues/native-integration_sending_asqn_[9,12].partial.md @@ -0,0 +1,15 @@ +### Custom envelope unwrapper + +Azure Storage Queues lacks native header support. NServiceBus solves this by wrapping headers and message body in a custom envelope structure. This envelope is serialized using the configured [serializer](/nservicebus/serialization) for the endpoint before being sent. + +Creating this envelope can cause unnecessary complexity if headers are not needed, as is the case in native integration scenarios. For this reason, NServiceBus.Transport.AzureStorageQueues 9.0 and above support configuring a custom envelope unwrapper. + +> [!WARNING] +> In this scenario, NServiceBus may place messages in your queue in addition to the native messages that are expected, for example if a message results in a [delayed retry](delayed-delivery.md). Any custom envelope unwrapper must verify if the incoming message is capable of being deserialized as a native message, and the resulting body must be serialized according to the configured endpoint serializer. + +The snippet below shows custom unwrapping logic that enables both NServiceBus formatted and plain serialized messages to be consumed. + +snippet: CustomEnvelopeUnwrapper + +> [!NOTE] +> This feature is currently NOT compatible with ServiceControl. A [ServiceControl transport adapter](/servicecontrol/transport-adapter.md) is required to leverage both.