In this article, let’s create Azure Service Bus resources, Azure Service Bus namespace and Queue using Azure CLI. Assign “Azure Service Bus Data Owner” role to Microsoft Entra (Azure AD) user name. Build a .NET console application using Azure.Messaging.ServiceBus SDK to send and receive the messages. Sign in to Azure and run the application. After this exercise, you will be able to send and receive messages from Azure Service Bus using .NET Client Library.
Following tasks are performed in this article:
Create Azure Service Bus resources.
Create Azure Service Bus namespace and queue.
Assign role to Microsoft Entra (Azure AD) username.
Send and Receive Messages using .NET Client Library.
Sign in to Azure and run Application.
Clean up resources.
Create Azure Service Bus resources
First basic task is to create and make ready Azure Service Bus resources to Azure using Azure CLI. Azure CLI (Azure Cloud Shell) is used to create the required resources. Azure CLI is the free Bash shell which can be run directly within the Azure portal. That is preinstalled and configured within the account. Perform the below steps one by one to achieve this.
Use Azure CLI (Azure Cloud Shell)
It is a free Bash shell which can be run directly within the Azure portal. It is preinstalled and configured within an account.
Click Cloud Shell button on the menu bar at the top right side of the Azure portal.
![Cloud Shell button]()
It will launch an interactive shell which can be used to run the steps outlined in this article. Select a Bash environment. To use code editor In cloud shell toolbar go to Settings menu and then select Go to Classic version.
![Cloud Shell Bash]()
Create resource group - Resource group is a logical container used to hold related resources. In it include the resources which you want to manage as a group. App configuration resource belongs to this resource group. Create it using az group create command.
az group create \
--name myResourceGroup1 \
--location eastus2
eastus2 is location code instead of it one can use their nearest region location.
Create variables - Here, several commands require unique names/values with same parameters. Hence, for easy to manege lets create some variables, assign values and reuse them in the command parameters. let command is used as below to create required variables.
let resourceGroup=myResourceGroup1 \
location=eastus2 \
namespaceName=myServiceBusNameSpace$RANDOM
Create Azure Service Bus namespace and Queue
In this section, lets create a Service Bus namespace, and then create a Queue. One by one perform the following steps in Azure CLI to achieve this.
Create Azure Service Bus namespace
az servicebus namespace create command is used to create an Azure Service Bus namespace and it will be used in .NET console application. This namespace is the logical container for service bus resources in Azure. It provides a unique container which allows to create one or more service bus.
az servicebus namespace create \
--name $namespaceName \
--location $location \
--resource-group $resourceGroup
Create Queue
Below az servicebus queue create command is used to create a Queue with name myQueue inside above created Service Bus namespace. This queue will be used to hold the messages.
az servicebus queue create \
--name myQueue \
--resource-group $resourceGroup \
--namespace-name $namespaceName
Assign role to Microsoft Entra (Azure AD) user
Let’s assign Microsoft Entra user to “Azure Service Bus Data Owner” role at the Service Bus namespace level to allow console application to send and receive messages. It is important to assign roles to Microsoft Entra (Azure AD) user name. Roles will define what access and permissions a user has within an organization’s Microsoft cloud environment. Roles determine what resources and actions a user can perform. “Azure Service Bus Data Owner” role is to be assigned to Microsoft Entra user which allows application to send and receive messages. One by one perform below steps in Azure CLI.
Retrieve userPrincipalName
First, retrieve userPrincipalName from account as mentioned in following command. It retrieves the information about currently authenticated user including their UPN and represents that who the role will be assigned to.
userPrincipal=$(az rest \
--method GET \
--url https://graph.microsoft.com/v1.0/me \
--headers 'Content-Type=application/json' \
--query userPrincipalName
--output tsv)
Retrieve resource ID
Second, get the resource ID of Service Bus namespace using below command. This will be used in next step to set scope for role assignment. Resource ID sets scope for role assignment to specific namespace.
resourceID=$(az servicebus namespace show \
--resource-group $resourceGroup \
--name $namespaceName\
--query id \
--output tsv)
Create and assign “Azure Service Bus Data Owner” role
Finally, create and assign “Azure Service Bus Data Owner” role using az role assignment create command. Command execution will create and assign “Azure Service Bus Data Owner” role which gives permission to send and receive the messages. This will give permissions to manage next routines. userPrincipal and resourceID variables are created in first and second steps which are used in this command to receive actual value at command execution time.
az role assignment create \
--assignee $userPrincipal\
--role "Azure Service Bus Data Owner" \
--scope $resourceID
Now, required basic resources are deployed and ready to use in console application.
Send and Receive Messages using .NET Client Library
Let’s set-up the .NET console application to send and receive the messages using .NET Client Library. Perform the following steps one by one in to Cloud Shell to achieve this.
.NET Project Setup
Set up one console application to send and receive message using .NET Client Library.
mkdir servicebus1
cd servicebus1
dotnet new console
dotnet add package Azure.Identity
dotnet add package Azure.Messaging.ServiceBus
Starter Code
Add the below starter code into the project and replace template code in Program.cs file by using editor in Cloud Shell.
code Program.cs
using System;
using System.Timers;
using Azure.Identity;
using Azure.Messaging.ServiceBus;
// Replace MY_NAMESPACE with actual Service Bus namespace
string serviceBusClientNameSpace = "MY_NAMESPACE.servicebus.windows.net";
string queueName = "myQueue";
// CREATE SERVICE BUS CLIENT
// SEND MESSAGES TO QUEUE
// PROCESS MESSAGES FROM QUEUE
// Dispose client
await objServiceBusClient.DisposeAsync();
Complete Code
Add following code one by one at mentioned commented section to complete the application. Let’s update the code for commented lines for specific operations one by one as described to create a service bus client to send messages to the queue and then process messages from the queue.
Create service bus client - In this section, let’s create DefaultAzureCredentialOptions object to configure DefaultAzureCredential credentials and then create a service bus client. Locate // CREATE SERVICE BUS CLIENT comment, then add following code directly beneath comment.
// CREATE SERVICE BUS CLIENT
// Create DefaultAzureCredentialOptions object to configure DefaultAzureCredential credentials
DefaultAzureCredentialOptions objDefaultAzureCredentialOptions = new()
{
ExcludeEnvironmentCredential = true,
ExcludeManagedIdentityCredential = true
};
// Create service bus client
ServiceBusClient objServiceBusClient = new(serviceBusClientNameSpace, new DefaultAzureCredential(objDefaultAzureCredentialOptions));
Send messages to queue - First, create a service bus sender and then create service bus message batch. Second, set total number of message to be sent to queue and add message to batch. Third, use producer client to send batch of messages to service bus queue. Locate // SEND MESSAGES TO QUEUE comment, then add following code directly beneath comment.
// SEND MESSAGES TO QUEUE
// Create service bus sender
ServiceBusSender objServiceBusSender = objServiceBusClient.CreateSender(queueName);
// Create service bus message batch
using ServiceBusMessageBatch objServiceBusMessageBatch = await objServiceBusSender.CreateMessageBatchAsync();
// Total number of message to be sent to queue
const int numberOfMessages = 4;
// Add random number to message
var random = new Random();
for (int i = 1; i <= numberOfMessages; i++)
{
int randomNumber = random.Next(1, 101);
string messageBody = $"Message - {randomNumber}";
// Add message to batch
if (!objServiceBusMessageBatch.TryAddMessage(new ServiceBusMessage(messageBody)))
{
// Generate error message if message is too large for batch
throw new Exception($"Message {i} is too large for batch and can't be sent!");
}
}
try
{
// Use producer client to send batch of messages to service bus queue
await objServiceBusSender.SendMessagesAsync(objServiceBusMessageBatch);
Console.WriteLine($"Batch of {numberOfMessages} messages has been published to queue successfully!");
}
finally
{
// Cleaned up network resources and other not managed objects
await objServiceBusSender.DisposeAsync();
}
Console.WriteLine("Press any key to receive and display messages!");
Console.ReadKey();
Process messages from queue - Locate // PROCESS MESSAGES FROM QUEUE comment, then add following code directly beneath comment. First, create a processor to process messages in queue and set idle timer timeout to stop processor for no messages in queue to process. Second, add handler to process messages and errors if any. Third, wait processor when to stop and display received messages.
// PROCESS MESSAGES FROM QUEUE
// Create processor to process messages in queue
ServiceBusProcessor objServiceBusProcessor = objServiceBusClient.CreateProcessor(queueName, new ServiceBusProcessorOptions());
// Set idle timer timeout to stop processor for no messages in queue to process
const int idleTimeOutMilliSeconds = 3000;
System.Timers.Timer idleTimer = new(idleTimeOutMilliSeconds);
idleTimer.Elapsed += async (s, e) =>
{
Console.WriteLine($"No messages received for {idleTimeOutMilliSeconds / 1000} seconds. Processor has been stopped!");
await objServiceBusProcessor.StopProcessingAsync();
};
try
{
// Add handler to process messages
objServiceBusProcessor.ProcessMessageAsync += MessageHandler;
// Add handler to process errors if any
objServiceBusProcessor.ProcessErrorAsync += ErrorHandler;
// Start processing
idleTimer.Start();
await objServiceBusProcessor.StartProcessingAsync();
Console.WriteLine($"Processor has been started and it will stop after {idleTimeOutMilliSeconds / 1000} seconds of inactivity!");
// Wait processor when to stop
while (objServiceBusProcessor.IsProcessing)
{
await Task.Delay(500);
}
idleTimer.Stop();
Console.WriteLine("All messages have been received successfully!");
Console.WriteLine("Press any key to Exit!");
Console.ReadKey();
}
finally
{
// Dispose processor
await objServiceBusProcessor.DisposeAsync();
}
// Display received messages
async Task MessageHandler(ProcessMessageEventArgs args)
{
string body = args.Message.Body.ToString();
Console.WriteLine($"Message received: {body}");
// Reset idle timer on each message
idleTimer.Stop();
idleTimer.Start();
// Complete message to delete from queue
await args.CompleteMessageAsync(args.Message);
}
// Generate error message if error occured during receiving messages
Task ErrorHandler(ProcessErrorEventArgs args)
{
Console.WriteLine(args.Exception.ToString());
return Task.CompletedTask;
}
Sign in to Azure and run Application
Now application is ready to run. One by one execute the following commands in Azure CLI to run an application and perform the mentioned steps to verify the result outcomes.
az login
dotnet run
Batch of 4 messages has been published to queue successfully!
Press any key to receive and display messages!
Processor has been started and it will stop after 3 seconds of inactivity!
Message received: Message - 7
Message received: Message - 43
Message received: Message - 75
Message received: Message - 21
No messages received for 3 seconds. Processor has been stopped!
All messages have been received successfully!
Press any key to Exit!
Clean up resources
Once finished the exercise its recommended to delete cloud resources are being created to avoid the unnecessary resource usage and any future costs. Deleting a resource group will delete all resources contained within it. Perform following steps one by one into Azure Portal to achieve this:
Navigate to resource group which is being created here and view its contents.
Delete resource group selection from the toolbar.
Choose resource group name and then follow next directions to delete resource group and all the resources it contains.
One can also clean up resources using Azure CLI as following:
az role assignment delete\
--role "Azure Service Bus Data Owner" \
--scope $resourceID
az servicebus queue delete \
--name myQueue \
--resource-group $resourceGroup \
--namespace-group $namespaceName\
az servicebus namespace delete \
--name $namespaceName\
--resource-group $resourceGroup
az group delete \
--name myResourceGroup1
Summary
Here, a complete process flow is described to send and receive messages from Azure Service Bus using .NET Client Library. Azure Service Bus resource is created using Azure CLI and assigned “Azure Service Bus Data Owner” role to Microsoft Entra (Azure AD) username. A .NET console application is developed using Azure.Messaging.ServiceBus SDK to send and receive messages. Finally, resources are cleaned up. A complete code of Program.cs file is attached with this article.