Sanitization with Azure Service Bus Transport

This page refers to the deprecated legacy Azure Service Bus transport that uses the WindowsAzure.ServiceBus NuGet package. All users should migrate to the Azure Service Bus transport transport.


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

Azure Service Bus Transport

This sample uses the Azure Service Bus Transport (Legacy).

Code walk-through

This sample has two endpoints

  • Publisher
  • Subscriber


Publisher publishes SomeEvent.

public class SomeEvent :
    public Guid EventId { get; set; }


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 to generate a valid rule name:

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