Ask me questions on twitter:
@leegunn.
Introduction
When moving from Windows Forms to ASP.NET Web Forms, an API that may be missed is that offered by the System.Windows.Forms.MessageBox
Class. Sometimes when developing web forms the application may wish to inform the user of a successful or, god forbid, an unsuccessful operation. An effective way to communicate an important message to the user is through the use a MessageBox
or, with respect to web programming, a JavaScript "alert".
The MessageBox
class in the System.Windows.Forms
namespace is usable only from Windows Forms and NOT ASP.NET Web Forms. In order to alert the user we need to inject some client side code into the HTML page. This is a simple task but can become quite a nuisance if this functionality is required on a regular basis.
I thought that it would be nice if we could simply call a static method from any page that would deal with the client side JavaScript required to display the alert's. I decided to write a small MessageBox
class with a static
Show();
method.
Using the code
To use this code in your projects, simply call the static Show()
method of the MessageBox
class and pass in the string that you wish to display to the user.
For example:
private void Page_Load( object sender, System.EventArgs e )
{
MessageBox.Show( "Hello World!" );
MessageBox.Show( "This is my second message." );
MessageBox.Show( "Alerts couldnt be simpler." );
}
As you can see from the example above, the developer isn't restricted to displaying one message box.
Behind the scenes
The first time the Show
method is invoked from a Page, a System.Collections.Queue
is created and stored in a private static HashTable
. The Queue is used to hold all of the message's associated with current executing Page. We also "wire up" the Page.UnLoad
event so we can write the client side JavaScript to the response stream after the Page has finished rendering its HTML.
The reason we store the Queue in a Hashtable
is because we are using static methods. There is the potential for multiple pages to be using the class at the same time (on separate threads). Therefore we need to make sure we know which messages belong to which page. To accomplish this we simply use the Page's reference as the key in the HashTable
. We obtain a reference to the current executing page by casting the current IHttpHandler
to System.Web.UI.Page
. The current IHttpHandler
can be obtained from HttpContext.Current.Handler
. In most cases this will be a class either directly or indirectly derived from System.Web.UI.Page
.
Source Code
public class MessageBox
{
private static Hashtable m_executingPages = new Hashtable();
private MessageBox(){}
public static void Show( string sMessage )
{
if( !m_executingPages.Contains( HttpContext.Current.Handler ) )
{
Page executingPage = HttpContext.Current.Handler as Page;
if( executingPage != null )
{
Queue messageQueue = new Queue();
messageQueue.Enqueue( sMessage );
m_executingPages.Add( HttpContext.Current.Handler, messageQueue );
executingPage.Unload += new EventHandler( ExecutingPage_Unload );
}
}
else
{
Queue queue = (Queue) m_executingPages[ HttpContext.Current.Handler ];
queue.Enqueue( sMessage );
}
}
private static void ExecutingPage_Unload(object sender, EventArgs e)
{
Queue queue = (Queue) m_executingPages[ HttpContext.Current.Handler ];
if( queue != null )
{
StringBuilder sb = new StringBuilder();
int iMsgCount = queue.Count;
sb.Append( "<script language="'javascript'">" );
string sMsg;
while( iMsgCount-- > 0 )
{
sMsg = (string) queue.Dequeue();
sMsg = sMsg.Replace( "\n", "\\n" );
sMsg = sMsg.Replace( "\"", "'" );
sb.Append( @"alert( """ + sMsg + @""" );" );
}
sb.Append( @"</script>" );
m_executingPages.Remove( HttpContext.Current.Handler );
HttpContext.Current.Response.Write( sb.ToString() );
}
}
}