Service Bus Sending Messages
Sending messages to Azure Service Bus involves creating a client connection, building the message, and using a sender object to deliver it to a queue or topic. This topic covers message sending using the official .NET SDK, Python SDK, and Azure CLI, along with batch sending and error handling patterns.
How Sending Works — Overview
[Producer App]
|
| 1. Create ServiceBusClient (connection string)
| 2. Create ServiceBusSender (target queue or topic)
| 3. Build ServiceBusMessage (body + properties)
| 4. Call SendMessageAsync()
|
v
[Azure Service Bus Queue / Topic]
(Message stored safely until receiver picks it up)
Sending a Message — .NET SDK
Install the NuGet Package
dotnet add package Azure.Messaging.ServiceBus
Send a Single Message to a Queue
using Azure.Messaging.ServiceBus;
string connectionString = "Endpoint=sb://myshopns.servicebus.windows.net/;...";
string queueName = "orders";
await using var client = new ServiceBusClient(connectionString);
await using var sender = client.CreateSender(queueName);
var order = new
{
orderId = 101,
customerId = "C456",
product = "Laptop",
amount = 1200.00
};
string json = System.Text.Json.JsonSerializer.Serialize(order);
var message = new ServiceBusMessage(BinaryData.FromString(json))
{
MessageId = "order-101",
Subject = "NewOrder",
ContentType = "application/json"
};
message.ApplicationProperties["Region"] = "India";
message.ApplicationProperties["Priority"] = "High";
await sender.SendMessageAsync(message);
Console.WriteLine("Message sent successfully.");
Send a Single Message to a Topic
string topicName = "order-events";
await using var sender = client.CreateSender(topicName);
var message = new ServiceBusMessage(BinaryData.FromString(json))
{
MessageId = "event-101",
Subject = "OrderPlaced"
};
await sender.SendMessageAsync(message);
Console.WriteLine("Event published to topic.");
Sending Batch Messages — .NET SDK
Sending messages one at a time creates many network round trips. Batch sending groups multiple messages into one operation, which improves throughput and reduces network cost.
await using var sender = client.CreateSender("orders");
// Create a batch
using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();
for (int i = 1; i <= 5; i++)
{
var msg = new ServiceBusMessage($"Order {i}");
if (!messageBatch.TryAddMessage(msg))
{
// Batch is full — send what we have and create a new batch
await sender.SendMessagesAsync(messageBatch);
Console.WriteLine($"Batch sent. Starting new batch from message {i}.");
messageBatch.Dispose();
messageBatch = await sender.CreateMessageBatchAsync();
messageBatch.TryAddMessage(msg);
}
}
// Send the last remaining batch
await sender.SendMessagesAsync(messageBatch);
Console.WriteLine("All batches sent.");
Batch Sending — How It Works
Batch 1: [msg1][msg2][msg3][msg4] --> sent in ONE network call Batch 2: [msg5][msg6][msg7] --> sent in ONE network call Total: 7 messages sent in 2 network calls (instead of 7 calls)
Sending Messages — Python SDK
Install the Package
pip install azure-servicebus
Send a Single Message
from azure.servicebus import ServiceBusClient, ServiceBusMessage
import json
connection_str = "Endpoint=sb://myshopns.servicebus.windows.net/;..."
queue_name = "orders"
order = {
"orderId": 101,
"product": "Laptop",
"amount": 1200.00
}
with ServiceBusClient.from_connection_string(connection_str) as client:
with client.get_queue_sender(queue_name) as sender:
msg = ServiceBusMessage(
body=json.dumps(order),
message_id="order-101",
subject="NewOrder",
content_type="application/json"
)
msg.application_properties = {
"Region": "India",
"Priority": "High"
}
sender.send_messages(msg)
print("Message sent.")
Send Batch Messages — Python
with ServiceBusClient.from_connection_string(connection_str) as client:
with client.get_queue_sender(queue_name) as sender:
batch = sender.create_message_batch()
for i in range(1, 6):
try:
batch.add_message(ServiceBusMessage(f"Order {i}"))
except ValueError:
# Batch is full — send and create a new one
sender.send_messages(batch)
batch = sender.create_message_batch()
batch.add_message(ServiceBusMessage(f"Order {i}"))
sender.send_messages(batch)
print("Batch sent.")
Sending Messages — Azure CLI
# Send a test message to a queue using CLI (useful for quick testing)
az servicebus queue message send \
--resource-group rg-messaging-prod \
--namespace-name myshopns \
--queue-name orders \
--message-body "{ \"orderId\": 101 }"
Sending with Managed Identity (Recommended for Production)
Instead of using a connection string (which contains a secret key), production applications should use Managed Identity with role-based access control. This eliminates the risk of exposing connection string secrets.
using Azure.Identity;
using Azure.Messaging.ServiceBus;
string namespaceFqdn = "myshopns.servicebus.windows.net";
string queueName = "orders";
// Uses the app's Managed Identity automatically
var client = new ServiceBusClient(namespaceFqdn, new DefaultAzureCredential());
var sender = client.CreateSender(queueName);
var message = new ServiceBusMessage("Order payload here");
await sender.SendMessageAsync(message);
Message Send Options
| Option | Method | When to Use |
|---|---|---|
| Single Message | SendMessageAsync(message) | Low volume, individual transactions |
| Batch Messages | SendMessagesAsync(batch) | High volume, bulk imports |
| Scheduled Message | Set ScheduledEnqueueTime | Delayed or future delivery |
| Send via Transaction | CreateTransaction() | Atomic multi-queue operations |
Error Handling During Send
try
{
await sender.SendMessageAsync(message);
Console.WriteLine("Message sent.");
}
catch (ServiceBusException ex) when (ex.Reason == ServiceBusFailureReason.MessagingEntityNotFound)
{
Console.WriteLine($"Queue not found: {ex.Message}");
}
catch (ServiceBusException ex) when (ex.Reason == ServiceBusFailureReason.QuotaExceeded)
{
Console.WriteLine("Queue is full. Increase queue size or speed up consumption.");
}
catch (ServiceBusException ex) when (ex.IsTransient)
{
// Transient errors are safe to retry
Console.WriteLine("Transient error — retry the send operation.");
}
catch (ServiceBusException ex)
{
Console.WriteLine($"Messaging error: {ex.Message}");
}
Common Send Errors
| Error Reason | Cause | Action |
|---|---|---|
| MessagingEntityNotFound | Queue or topic does not exist | Check the name and namespace |
| QuotaExceeded | Queue or namespace has reached storage limit | Increase size limit or add consumers |
| Unauthorized | Invalid connection string or insufficient permissions | Verify access policy or RBAC role |
| MessageSizeExceeded | Message body is larger than the tier limit | Compress the body or upgrade to Premium tier |
| ServiceCommunicationError (transient) | Temporary network issue | Retry with exponential backoff |
Best Practices for Sending Messages
- Always set a unique MessageId to enable duplicate detection
- Use batch sending for high-volume message flows to reduce network overhead
- Use Managed Identity in production — avoid hardcoding connection strings
- Set ContentType to help receivers deserialize the body correctly
- Set TimeToLive to prevent stale messages from accumulating in the queue
- Wrap send operations in try-catch and retry on transient errors
- Dispose the sender and client properly using
await usingorusingblocks
Summary
Sending messages to Azure Service Bus requires a client connection, a sender targeting a specific queue or topic, and a message with a body and optional properties. Batch sending improves efficiency for high-volume flows. Managed Identity removes the need for connection string secrets in production. Proper error handling and retries ensure messages reach Service Bus reliably even during transient failures.
