Sanitization with Azure Service Bus Transport

Component: Azure Service Bus Transport
NuGet Package NServiceBus.Azure.Transports.WindowsAzureServiceBus (7.x)
Target NServiceBus Version: 6.x


An environment variable named AzureServiceBus.ConnectionString with the connection string for the Azure Service Bus namespace.

Azure Service Bus Transport

This sample utilizes the Azure Service Bus Transport.

Code walk-through

This sample has two endpoints

  • Publisher
  • Subscriber
public class SomeEvent :
    public Guid EventId { get; set; }


Publisher publishes SomeEvent.


Subscriber subscribes to and handles SomeEvent. The topology used by the endpoints is ForwardingTopology, which creates a subscription named Subscriber and creates a rule for each event the endpoint subscribes to.

SomeEvent full name is Shared.Messages.In.A.Deep.Nested.Namespace.Nested.Events.SomeEvent. That is 72 characters which exceed the maximum 50 characters limit for a rule name. An attempt to use such a long rule name will result in the following exception:

Invalid Rule name 'Shared.Messages.In.A.Deep.Nested.Namespace.Nested.Events.SomeEvent' that cannot be used with Azure Service Bus. Rule name exceeds maximum allowed length or contains invalid characters. Check for invalid characters, shorten the name, or use 'Sanitization().UseStrategy()' configuration extension.`

Creating custom sanitization

Registering custom sanitization

For the purpose of this sample, custom sanitization based on a SHA1 hashing algorithm will be used:

class Sha1Sanitization :
    public string Sanitize(string entityPathOrName, EntityType entityType)
        // remove invalid characters
        if (entityType == EntityType.Queue || entityType == EntityType.Topic)
            var regexQueueAndTopicValidCharacters = new Regex(@"[^a-zA-Z0-9\-\._\/]");
            var regexLeadingAndTrailingForwardSlashes = new Regex(@"^\/|\/$");

            entityPathOrName = regexQueueAndTopicValidCharacters.Replace(entityPathOrName, string.Empty);
            entityPathOrName = regexLeadingAndTrailingForwardSlashes.Replace(entityPathOrName, string.Empty);

        if (entityType == EntityType.Subscription || entityType == EntityType.Rule)
            var rgx = new Regex(@"[^a-zA-Z0-9\-\._]");
            entityPathOrName = rgx.Replace(entityPathOrName, "");

        var entityPathOrNameMaxLength = 0;

        switch (entityType)
            case EntityType.Queue:
            case EntityType.Topic:
                entityPathOrNameMaxLength = 260;
            case EntityType.Subscription:
            case EntityType.Rule:
                entityPathOrNameMaxLength = 50;

        // hash if too long
        if (entityPathOrName.Length > entityPathOrNameMaxLength)
            entityPathOrName = SHA1DeterministicNameBuilder.Build(entityPathOrName);

        return entityPathOrName;

Generated hash (20 bytes) will be formatted into eight groups of 8 characters each for readability:

static class SHA1DeterministicNameBuilder
    public static string Build(string input)
        using (var provider = new SHA1CryptoServiceProvider())
            var inputBytes = Encoding.Default.GetBytes(input);
            var hashBytes = provider.ComputeHash(inputBytes);

            var hashBuilder = new StringBuilder(string.Join("", hashBytes.Select(x => x.ToString("x2"))));
            foreach (var delimeterIndex in new[]
                hashBuilder.Insert(delimeterIndex, "-");
            return hashBuilder.ToString();

Custom strategy registration:

var sanitization = transport.Sanitization();

Generated rule name:


Related Articles

Last modified