ASP.NET page automatically notifies when MSMQ message arrives



Recently I came across a forum query. The query was like: There is one source from which a message was sent to MSMQ and a web interface aka an asp.net page would display the newly added message automatically without any user intervention. In order to replicate the situation, I created two .NET projects; one is a simple console application and another is a web application. The console application would compose the message and send it to the MSMQ continuously using an infinite loop. The Web application connects to MSMQ and displays the message in a gridview using ajax updatepanel which is asynchronously triggered by an ajax timer control.

Time to Start with console application. I assume that you have MSMQ feature installed on your server and you are using VS 2010.

In console application, I created a very simple method to create a queue; composing and sending the message to the queue using the following code snippet.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;
using System.Threading;

namespace MSMQSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //Infinite loop executed in the 5 seconds interval
            while (true)
            {
                SendMessage();
                Thread.Sleep(5000);
            }
        }
        // Method to create queue, compose message and sending message to queue
        private static void SendMessage()
        {
            try
            {
                const string MSG_QUEUE = @".\private$\TestQueue";

                MessageQueue _msgQueue = null;

                if (MessageQueue.Exists(MSG_QUEUE))
                {
                    _msgQueue = new MessageQueue(MSG_QUEUE);
                }
                else
                {
                    MessageQueue.Create(MSG_QUEUE);
                }

                string _msgText = String.Format("Message sent at {0}", DateTime.Now.ToString());

                 Message _msg = new Message();
                _msg.Body = _msgText;
                _msg.Label = new Guid().ToString();
                _msgQueue.Send(_msg);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc);
            }
        }
    }
}

Running this console application would create the message and send the message to MSMQ.

Now you need to create one web application with one aspx page. The aspx page contains one ajax timer, ajax updatepanel and gridview control. I use timer control to invoke the method on each tick event (interval of 5 seconds) of it and update the gridview control using partial update (because I put the gridview with the updatepanel).

I also have a custom class MSMQMessage to store the message label and body. You can add/remove properties from it according to your requirement. Basically, I am binding a list of MSMQMessages with the gridview control.

The aspx code looks like

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MSMQSample.Web.Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title
>
</head>
<
body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
        <asp:Timer ID="UpdateTimer" runat="server" Interval="5000" OnTick="UpdateTimer_Tick"></asp:Timer>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <Triggers>
        <asp:AsyncPostBackTrigger ControlID="UpdateTimer" EventName="Tick" />
        </Triggers>
        <ContentTemplate>
        <asp:GridView ID="grdMessage" runat="server">       
        </asp:GridView>
        </ContentTemplate>
        </asp:UpdatePanel>       
    </div>
    </form
>
</body>
</
html>

The MSMQMessage class code is

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MSMQSample.Web
{
    public class MSMQMessage
    {
        public string Label {get;set;}
        public string Body{get;set;}
    }
}


In codebehind, I write one method to read the message from queue, bind the gridview with list of message and call this method on tick event of timer. This is achieved using following code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Messaging;
using System.Threading;

namespace MSMQSample.Web
{
    public partial class Default : System.Web.UI.Page
    {
        const string MSG_QUEUE = @".\private$\TestQueue";       

        protected void Page_Load(object sender, EventArgs e)
        {
            if(!IsPostBack)
            {
                UpdateGUI();
            }
        }

        protected void UpdateTimer_Tick(object sender, EventArgs e)
        {
            UpdateGUI();
        }

        private void UpdateGUI()
        {
            try
            {
                MessageQueue _msgQueue = null;
                IList<MSMQMessage> _msgList = new List<MSMQMessage>();

                if (MessageQueue.Exists(MSG_QUEUE))
                {
                    _msgQueue = new MessageQueue(MSG_QUEUE);
                }
                else
                {
                    throw new Exception("Message Queue does not exist");
                }

                foreach (Message _message in _msgQueue.GetAllMessages())
                {
                    MSMQMessage _msmqmessage = new MSMQMessage();                   
 
                    _msmqmessage.Label = _message.Label;
                    _message.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" });
                    _msmqmessage.Body = _message.Body.ToString();
                    _msgList.Add(_msmqmessage);
                }

                grdMessage.DataSource = _msgList;
                grdMessage.DataBind();
            }
            catch
            {
                throw;
            }
        }
    }
}


It is obvious that the updateGUI method would be called by the Timer's tick event in the interval of 5 seconds and it will bind the list of messages with the gridview.

How to test the application. First run the aspx page. Initially it will not display anything because you don't have any message in the queue.

Right click on console application from solution explorer and click on Debug -> Start New Instance.

asp.net.gif

That's it. Now when you show the aspx page the gridview is automatically refreshed and shows you the latest messages.


Similar Articles