Introduction
In this article, I am implementing multi-tier application of sending and receiving messages through the Azure Service Bus queue.
Azure Service Bus queue is being used as a repository for First In First Out (FIFO) message processing. A sender sends a message to a queue, where it waits until a receiver picks it.
Background
To demonstrate “Service Bus” I will use a popular Pizza Order Delivery process. Example: When a customer orders pizza, the order will stay in the queue until the order is picked to be processed.
I named the application "Amazing Pizza Order Delivery". Pizza Orders will be placed by the customers through an MVC portal (Web Role). The order will be processed by a background processor (Worker Role).
Implementation
First you need to have an Azure Account to implement the Service Bus. Once your account is set up, go to Azure UI and click on "Create a resource". Please note that the Azure Layout changes time to time so it might look different at the time you are reading this article.

Then Click on "+ Add" button and enter a unique Service Bus Name.
In this case, opted for "AmazingServiceBus". Select appropriate pricing, subscription, and location (nearest geographical). Select an existing resource group or create a new one.
When all necessary information is filled out, click on "Create service bus namespace". It will start creating the namespace.
The notification will show "Deployment" and then "Success" message.
Deployment in progress...



Once the "Queue" is set up in Azure, let's start creating a Web UI.
Open VS (VS 2017) in admin mode and select "Azure Cloud Service", name the application "AmazingDeliveryService".



- public static class Connector
- {
- public const string NameSpace = "amazingservicebus"; // service bus name
- public const string QueueName = "deliveryorderqueue"; // queue name
- public const string key = "Primary key from servicebus";
- public static QueueClient OrdersQueueClient;
- public static NamespaceManager CreateNamespaceManager()
- {
- var uri = ServiceBusEnvironment.CreateServiceUri(
- "sb", NameSpace, String.Empty);
- var tP = TokenProvider.CreateSharedAccessSignatureTokenProvider(
- "RootManageSharedAccessKey", key);
- return new NamespaceManager(uri, tP);
- }
- public static void Initialize()
- {
- ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;
- var namespaceManager = CreateNamespaceManager();
- var messagingFactory = MessagingFactory.Create
- (namespaceManager.Address, namespaceManager.Settings.TokenProvider);
- OrdersQueueClient = messagingFactory.CreateQueueClient(QueueName);
- }
- }
Now, I will create a class for message transfer. I will call it "DeliveryModel" and will add it in "DeliveryModel.cs" file in model folder. Display name will be used to change the labels on Web UI.
Note: We will be using the same file to send and receive message- public class DeliveryModel
- {
- [DisplayName("Customer Name")]
- public string CustomerName { get; set; }
- [DisplayName("Product Name")]
- public string ProductName { get; set; }
- }
Now change the "HomeController" class
- public class HomeController : Controller
- {
- public ActionResult Index()
- {
- return RedirectToAction("Submit");
- }
- public ActionResult About()
- {
- ViewBag.Message = "Your application description page.";
- return View();
- }
- public ActionResult Contact()
- {
- ViewBag.Message = "Your contact page.";
- return View();
- }
- public ActionResult Submit()
- {
- var namespaceManager = Connector.CreateNamespaceManager();
- var queue = namespaceManager.GetQueue(Connector.QueueName);
- ViewBag.MessageCount = queue.MessageCount;
- return View();
- }
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Submit(DeliveryModel order)
- {
- if (ModelState.IsValid)
- {
- var message = new BrokeredMessage(order);
- Connector.OrdersQueueClient.Send(message);
- return RedirectToAction("Submit");
- }
- else
- {
- return View(order);
- }
- }
- }
Right click on Submit and add a "Submit.cshtml" view. Tie Delivery Model as Model so it can generate automatic UI.

- @model AmazingFrontendWebRole.Models.DeliveryModel
- @{
- ViewBag.Title = "Product Order";
- }
- <h2>Submit</h2>
- @using (Html.BeginForm())
- {
- @Html.AntiForgeryToken()
- <div class="form-horizontal">
- <h4>Please input Customer Name & Product Name,
- then click Order. Total Order Count : @ViewBag.MessageCount </h4>
- <hr />
- @Html.ValidationSummary(true, "", new { @class = "text-danger" })
- <div class="form-group">
- @Html.LabelFor(model => model.CustomerName,
- htmlAttributes: new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.CustomerName,
- new { htmlAttributes = new { @class = "form-control" } })
- @Html.ValidationMessageFor(model => model.CustomerName, "",
- new { @class = "text-danger" })
- </div>
- </div>
- <div class="form-group">
- @Html.LabelFor(model => model.ProductName,
- htmlAttributes: new { @class = "control-label col-md-2" })
- <div class="col-md-10">
- @Html.EditorFor(model => model.ProductName,
- new { htmlAttributes = new { @class = "form-control" } })
- @Html.ValidationMessageFor(model => model.ProductName,
- "", new { @class = "text-danger" })
- </div>
- </div>
- <div class="form-group">
- <div class="col-md-offset-2 col-md-10">
- <input type="submit"
- value="Order" class="btn btn-default" />
- </div>
- </div>
- </div>
- }
- <div>
- @Html.ActionLink("Back to List", "Index")
- </div>
- @section Scripts {
- @Scripts.Render("~/bundles/jqueryval")
- }
Change the "_Layout.cshtml" file to remove unwanted options...
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>@ViewBag.Title - My ASP.NET Application</title>
- @Styles.Render("~/Content/css")
- @Scripts.Render("~/bundles/modernizr")
- </head>
- <body>
- <div class="navbar navbar-inverse navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <button type="button" class="navbar-toggle"
- data-toggle="collapse" data-target=".navbar-collapse">
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- @Html.ActionLink("Product Order", "Index", "Home",
- new { area = "" }, new { @class = "navbar-brand" })
- </div>
- <div class="navbar-collapse collapse">
- </div>
- </div>
- </div>
- <div class="container body-content">
- @RenderBody()
- <hr />
- <footer>
- <p>© @DateTime.Now.Year - My ASP.NET Application</p>
- </footer>
- </div>
- @Scripts.Render("~/bundles/jquery")
- @Scripts.Render("~/bundles/bootstrap")
- @RenderSection("scripts", required: false)
- </body>
- </html>
Call "Connector.Initialize()" in Application_Start() method.
- protected void Application_Start()
- {
- AreaRegistration.RegisterAllAreas();
- FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- BundleConfig.RegisterBundles(BundleTable.Bundles);
- Connector.Initialize();
- }

When you submit an order, you will see the total number of orders in "Total Order Count".
You will also be able to see the total number of messages available in a queue in Azure.
Let's create an application to consume messages. Remember these messages will stay in the queue until consumer doesn't consume.
To create a consumer, we will use Cloud application but this time with a worker role. Create a new VS cloud application named "DeliveryProvider" assuming this will only consume orders from Service Bus Queue.



- public class DeliveryModel
- {
- [DisplayName("Customer Name")]
- public string CustomerName { get; set; }
- [DisplayName("Product Name")]
- public string ProductName { get; set; }
- }
- public class WorkerRole : RoleEntryPoint
- {
- // The name of your queue
- const string QueueName = "deliveryorderqueue";
- QueueClient Client;
- ManualResetEvent CompletedEvent = new ManualResetEvent(false);
- public override void Run()
- {
- Trace.WriteLine("Starting processing of messages");
- Client.OnMessage((receivedMessage) =>
- {
- try
- {
- Trace.WriteLine("Processing", receivedMessage.SequenceNumber.ToString());
- var order = receivedMessage.GetBody<DeliveryModel>();
- Trace.WriteLine(order.CustomerName + ": " + order.ProductName, "ProcessingMessage");
- receivedMessage.Complete();
- }
- catch (Exception ex)
- {
- // Handle any message processing specific exceptions here
- }
- });
- CompletedEvent.WaitOne();
- }
- public override bool OnStart()
- {
- // Set the maximum number of concurrent connections
- ServicePointManager.DefaultConnectionLimit = 4;
- string connectionString = CloudConfigurationManager.GetSetting
- ("Microsoft.ServiceBus.ConnectionString");
- var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
- Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
- return base.OnStart();
- }
- public override void OnStop()
- {
- Client.Close();
- CompletedEvent.Set();
- base.OnStop();
- }
- }
As you will see, the code I am trying to connect "deliveryorderqueue" from the connection string specified in Properties->Settings.
Go ahead and run this application. This will run in Azure Emulator in a local machine. Once it runs, it will start consuming orders from the "deliveryorderqueue". When you go to the Azure queue count, the number of orders will be reduced by the number of messages that have been read.

Uma PlPosted Sep 4, 2019, 6:23 AM
The type or namespace NamescriptManager is not available, it throws this err, added windowsazure.servicebus, Microsoft.Azure.ServiceBus