Как вы получаете доступ к подкатегории "мертвая буква" в подписке Azure?

Когда я использую следующее:

var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(topicPath,subName);
var client = SubscriptionClient.CreateFromConnectionString(connectionString, deadLetterPath, subName);

Я получаю InvalidOperationException

Невозможно напрямую создать клиента в под-очереди. Создайте клиента в главной очереди и используйте его для создания получателей в соответствующей подпоследовательности.

В некоторых частях документации Azure говорится, что для доступа к подпоследовательности используется SubscriptionClient.CreateReceiver, но этот метод не существует.

Ответ 1

Этот подход работает для вас?

MessagingFactory factory = MessagingFactory.CreateFromConnectionString(cnxString);
var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(topicPath,subName);
var dlqReceiver = factory.CreateMessageReceiver(deadLetterPath, ReceiveMode.ReceiveAndDelete);

Я не проверял это здесь (на собрании), но попробую

ура

Ответ 2

Существует соглашение об именовании очереди недоставленных сообщений с использованием служебной шины Azure:

  • Для очереди служебной шины: queuePath/$ DeadLetterQueue
  • Для подписки служебной шины: topicPath/subscriptionName/$ DeadLetterQueue

Таким образом, вы можете получить доступ к очередям мертвых писем так же, как и к своим очередям.

Из ответа @SamVanhoutte вы можете видеть, что инфраструктура ServiceBus предоставляет методы для форматирования имени очереди недоставленных сообщений:

  • Для очереди служебной шины: QueueClient.FormatDeadLetterPath(queuePath)

  • Для подписки служебной шины: SubscriptionClient.FormatDeadLetterPath(topicPath, subscriptionName)

Я написал два небольших метода для создания получателя сообщений для очереди и подписки, где вы можете установить, хотите ли вы очередь письма о сделке или нет:

/// <summary>
/// Create a new <see cref="MessageReceiver"/> object using the specified Service Bus Queue path.
/// </summary>
/// <param name="connectionString">The connection string to access the desired service namespace.</param>
/// <param name="queuePath">The Service Bus Queue path.</param>
/// <param name="isDeadLetter">True if the desired path is the deadletter queue.</param>
public static MessageReceiver CreateMessageReceiver(string connectionString, string queuePath,
    bool isDeadLetter = false)
{
    return MessagingFactory.CreateFromConnectionString(connectionString)
        .CreateMessageReceiver(isDeadLetter
            ? QueueClient.FormatDeadLetterPath(queuePath)
            : queuePath);
}

/// <summary>
/// Create a new <see cref="MessageReceiver"/> object using the specified Service Bus Topic Subscription path.
/// </summary>
/// <param name="connectionString">The connection string to access the desired service namespace.</param>
/// <param name="topicPath">The Service Bus Topic path.</param>
/// <param name="subscriptionName">The Service Bus Topic Subscription name.</param>
/// <param name="isDeadLetter">True if the desired path is the deadletter subqueue.</param>
public static MessageReceiver CreateMessageReceiver(string connectionString, string topicPath,
    string subscriptionName, bool isDeadLetter = false)
{
    return MessagingFactory.CreateFromConnectionString(connectionString)
        .CreateMessageReceiver(isDeadLetter
            ? SubscriptionClient.FormatDeadLetterPath(topicPath, subscriptionName)
            : SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName));
}

Ответ 3

Если вы используете Microsoft.Azure.ServiceBus вместо Microsoft.ServiceBus, это немного отличается.

var deadQueuePath = EntityNameHelper.FormatDeadLetterPath(your_queue_name);
var deadQueueReceiver = new MessageReceiver(connectionString, deadQueuePath);

EntityNameHelper классу EntityNameHelper в пространстве имен Microsoft.Azure.ServiceBus, для тем используйте путь подписки вместо your_queue_name.

Имя очереди или путь подписки.

/// <summary>
/// Formats the dead letter path for either a queue, or a subscription.
/// </summary>
/// <param name="entityPath">The name of the queue, or path of the subscription.</param>
/// <returns>The path as a string of the dead letter entity.</returns>
public static string FormatDeadLetterPath(string entityPath)
{
    return EntityNameHelper.FormatSubQueuePath(entityPath, EntityNameHelper.DeadLetterQueueName);
}

Ответ 4

Те, кто хочет сделать это на питоне.

Получать сообщения из очереди недоставленных писем:

from azure.servicebus import ServiceBusClient
import json
connectionString = "Your Connection String to Service Bus"
serviceBusClient = ServiceBusClient.from_connection_string(connectionString)
queueName = "Your Queue Name created in the Service Bus"
queueClient = serviceBusClient.get_queue(queueName)
with queueClient.get_deadletter_receiver(prefetch=5) as queueReceiver:
    messages = queueReceiver.fetch_next(timeout=100)
    for message in messages:
        # message.body is a generator object. Use next() to get the body.
        body = next(message.body)
        message.complete()

Надеюсь, это кому-нибудь поможет.