DEV Community

loading...
Cover image for Azure Service Bus with Asp.Net Core 5

Azure Service Bus with Asp.Net Core 5

moe23 profile image Mohamad Lawand ・6 min read

In this article we will be exploring how to implement Azure Service bus with Asp.Net Core 5.

You can watch the entire video step by step on YouTube:

You can find the source code on GitHub:
https://github.com/mohamadlawand087/v14-AzureServiceBusWithAspNet5

So what are we going to cover today:

  • What do we need to get started
  • What are we going to build
  • Azure Service bus basics
  • The structure of our application
  • Code

If you find this video helpful, please like, share and subscribe as it will really help the channel.

Before we start you will need to have

Links will be available in the description down below

So what are we going to build today, we will build a sample application which will contain a form which will collect data from the user and once that user submits the data we will want to send them an email confirming that we have received their information.

We will be covering Azure Service bus fundamentals, i have made a more in-depth video about Azure Service bus which you can find in the description and on the upper right hand corner.

In essence Azure Service Bus is a way to send a message from point a to point b. it means that i am going to put the info that i want to send somewhere and the specific service thats needs it will pick it up.

Azure Service bus leverage the idea of async process in the message queue and its very durable.

Once we publish a message to the queue its very hard to loose that data. So what is a message and what a queue

Message: Json Object which will contain all of the information that we need to send

Queue: a list of data items (Messages) stored to be retrievable in a definite order, usually the order of insertion (FIFO)

So how will the communication between our application and email service work. This is where message and queue comes into place.

When the web application collects its data from the user

  • a message will be created
  • that message will be sent on the service bus
  • our email service will pick up that message
  • and the mail service will send the email

We will be building 2 applications and 1 class-library, the first is an MVC application which will be responsible for sending the request, a console application which will be receiving it and outputting the results. The class-library will share classes between the projects for more reusable code.

We will start by creating an Asp.Net Core MVC application

dotnet new mvc -n "SampleWebSender" -lang "C#" 
Enter fullscreen mode Exit fullscreen mode

Class-library

dotnet new classlib -n "SampleShared"
Enter fullscreen mode Exit fullscreen mode

Console Application

dotnet new console -n "SampleAppReceiver"
Enter fullscreen mode Exit fullscreen mode

Once those applications are created we will need to add reference to the Class-library to the console application and the mvc project

dotnet add SampleWebSender/SampleWebSender.csproj reference SampleShared/SampleShared.csproj
dotnet add SampleAppReceiver/SampleAppReceiver.csproj reference SampleShared/SampleShared.csproj
Enter fullscreen mode Exit fullscreen mode

The next step is to install some packages to our application, will start by installing packages to our MVC application, we will need to navigate to our application and install it

dotnet add package Microsoft.Azure.ServiceBus --version 5.1.1
Enter fullscreen mode Exit fullscreen mode

We will need to do the same step for our console application, we will need to navigate to our application and install it

dotnet add package Microsoft.Azure.ServiceBus --version 5.1.
Enter fullscreen mode Exit fullscreen mode

We will start by add model classes to our class library so inside our SampleShared library lets create a new folder called Model

Inside that folder will create a class called Person

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Inside our MVC application we need to open the appsettings.json and add the ConnectionString section

"ConnectionStrings" : {
    "AzureServiceBus" : ""
  }
Enter fullscreen mode Exit fullscreen mode

Inside our MVC application, we need to create a new folder called Services and will add to it a class and an interface called AzureBusService and IAzureBusService

public interface IAzureBusService
{
    Task SendMessageAsync(Person serviceBusMessage, string queueName);
}
Enter fullscreen mode Exit fullscreen mode
public class AzureBusService : IAzureBusService
{
    private readonly IConfiguration _config;

    public AzureBusService(IConfiguration config)
    {
        _config = config;
    }

    public async Task SendMessageAsync(Person serviceBusMessage, string queueName)
    {
        var queueClient = new QueueClient(_config.GetConnectionString("AzureServiceBus"), queueName);

        // we convert the annonymous obj to a json
        var msgBody = JsonSerializer.Serialize(serviceBusMessage);

        var msg = new Message(Encoding.UTF8.GetBytes(msgBody));

        await queueClient.SendAsync(msg);            
    }
}
Enter fullscreen mode Exit fullscreen mode

Next step will be to go to our startup class and adding our service inside our ConfigureService method

services.AddTransient<IAzureBusService, AzureBusService>();
Enter fullscreen mode Exit fullscreen mode

Now lets navigate to Azure and create a service bus

1- lets navigate to portal.azure.com

2- login or register if you don't have an account

3- Click on create resource

4- In the search bar type "Service bus"

5- Click on Service bus

6- Click on create

7- Choose a resource group name

8- Enter the Namespace name

9- Choose a location

10- Select Pricing tier: Basic

11- Click review and create

12- After it has been create will navigate to the resource group

13- Inside of our Service bus we need to go to Shared access policies

14- Will click on RootManageSharedAccessKey

15- in open tab lets copy the Primary connection string

Once we have the connection string lets go back to visual studio and will update our appsettings.json with the connection string

"ConnectionStrings" : {
    "AzureServiceBus" : "Endpoint=sb://samplebus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=VmU54+VIQaUp5P4Rl0y6No/eK85MhjjnhIY5Z86HYXw="
  }
Enter fullscreen mode Exit fullscreen mode

Now lets go back to Azure and go to our Service Bus resource, inside the resource we need to select Queues.

Click on + Queue and fill the form as follow,

  • Name: MessageQueue
  • Queue Size: 1G
  • Max Delivery counts: 10 (if the lock duration is expired the message is unlocked and put back in the queue) if this happens 10 time it will go to the dead letter queue
  • We don't change anything else and click on save

The queue is now created for us "MessageQueue"

Lets go back to VS code and open our HomeController inside the controllers folder

So inside our index action let's create the post action for Index which will be responsible for collection the information from the users and sending it to the Queue

private readonly ILogger<HomeController> _logger;
private readonly IAzureBusService _busService;

public HomeController(ILogger<HomeController> logger, IAzureBusService busService)
{
    _logger = logger;
    _busService = busService;
}

public IActionResult Index()
{
    return View();
}

[HttpPost]
public async Task<IActionResult> Index(Person person)
{
    await _busService.SendMessageAsync<Person>(person, "emailqueue");
    return RedirectToAction("Privacy");
}
Enter fullscreen mode Exit fullscreen mode

Views

<form asp-action="Index" asp-controller="Home" method="POST">
    <div class="row">
         <div class="form-group">
                <label>First Name:</label>
                <input asp-for="FirstName" type="text" class="form-control required" placeholder="Enter First Name">
            </div>

         <div class="form-group">
                <label>Last Name:</label>
                <input asp-for="LastName" type="text" class="form-control required" placeholder="Enter Last Name">
            </div>

         <div class="form-group">
                <label>Email:</label>
                <input asp-for="Email" type="text" class="form-control required" placeholder="Enter Email">
            </div>
    </div>


    <button type="submit" class="btn btn-succees">Save</button>
</form>
Enter fullscreen mode Exit fullscreen mode

Now lets run the application and see if we are able to see the messages in Azure.

Next we will build our console app which will be responsible to receiving the message and sending the email, the email functionality we will be adding in a future video for now we will be just displaying the name and the email of the person

Console app

class Program
{
    const string connectionString = "Endpoint=sb://samplebus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=VmU54+VIQaUp5P4Rl0y6No/eK85MhjjnhIY5Z86HYXw=";
    const string queueName = "emailqueue";
    static IQueueClient queueClient;

    static async Task Main(string[] args)
    {
        queueClient = new QueueClient(connectionString, queueName);
        var msgHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
        {
            // hpw many messages we want to process at a time
            MaxConcurrentCalls = 1,
            // needs to wait until the message is processed not only read
            AutoComplete = false
        };

        // register a method handler, this is the method that is going to be called when there is a new message
        // this method will stay and run in the background
        queueClient.RegisterMessageHandler(ProcessMessageAsync, msgHandlerOptions);
        Console.ReadLine();
        await queueClient.CloseAsync();
    }

    private static async Task ProcessMessageAsync(Message msg, CancellationToken token)
    {
        var jsonString = Encoding.UTF8.GetString(msg.Body);
        var person = JsonSerializer.Deserialize<Person>(jsonString);

        Console.WriteLine($"Email will be send to: {person.FirstName} {person.LastName} Email: {person.Email}");

        // Email logic to be added

        // Since in our options we have specified that the auto complete is false
        // we need to tell the queue that its completed here
        // we are taking the lock token and updating the queue that the message is completed
        await queueClient.CompleteAsync(msg.SystemProperties.LockToken);
    }

    private static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs arg)
    {
        Console.WriteLine($"Message Handler Exception: {arg.Exception}");
        return Task.CompletedTask;
    }
}
Enter fullscreen mode Exit fullscreen mode

Thank you for reading

Discussion (0)

pic
Editor guide