ASP.NET 中的简单消息框功能
一篇文章,描述如何在 ASP.NET 中提供简单的消息框功能。
引言
从 Windows Forms 迁移到 ASP.NET Web Forms 时,可能会缺失的一个 API 是 System.Windows.Forms.MessageBox
类提供的 API。 在开发 Web Forms 时,应用程序有时可能希望告知用户操作成功或(天哪)操作失败。 通过使用 MessageBox
或,就 Web 编程而言,JavaScript “alert” 是向用户传达重要消息的有效方法。
System.Windows.Forms
命名空间中的 MessageBox
类只能从 Windows Forms 使用,而不能从 ASP.NET Web Forms 使用。 为了提醒用户,我们需要将一些客户端代码注入到 HTML 页面中。 这项任务很简单,但如果需要此功能,可能会变得很麻烦。
我想如果我们能从任何页面简单地调用一个静态方法,该方法可以处理显示警报所需的客户端 JavaScript,那就太好了。 我决定编写一个带有 static
Show();
方法的小型 MessageBox
类。
使用代码
要在您的项目中使用的代码,只需调用 MessageBox
类的静态 Show()
方法,并传入您希望显示给用户的字符串即可。
例如
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." );
}
如上例所示,开发人员不受限制只能显示一个消息框。
幕后
第一次从页面调用 Show
方法时,将创建一个 System.Collections.Queue
并将其存储在私有的静态 HashTable
中。 Queue 用于保存与当前执行页面相关联的所有消息。 我们还“绑定”了 Page.UnLoad
事件,以便在页面完成呈现其 HTML 后,我们可以将客户端 JavaScript 写入响应流。
我们之所以将 Queue 存储在 Hashtable
中,是因为我们正在使用静态方法。 存在多个页面同时使用该类的可能性(在不同的线程上)。 因此,我们需要确保我们知道哪些消息属于哪个页面。 为了实现这一点,我们只需使用页面的引用作为 HashTable
中的键。 我们通过将当前的 IHttpHandler
转换为 System.Web.UI.Page
来获取当前执行页面的引用。 当前的 IHttpHandler
可以从 HttpContext.Current.Handler
获得。 在大多数情况下,这将是直接或间接从 System.Web.UI.Page
派生的一个类。
源代码
public class MessageBox
{
private static Hashtable m_executingPages = new Hashtable();
private MessageBox(){}
public static void Show( string sMessage )
{
// If this is the first time a page has called this method then
if( !m_executingPages.Contains( HttpContext.Current.Handler ) )
{
// Attempt to cast HttpHandler as a Page.
Page executingPage = HttpContext.Current.Handler as Page;
if( executingPage != null )
{
// Create a Queue to hold one or more messages.
Queue messageQueue = new Queue();
// Add our message to the Queue
messageQueue.Enqueue( sMessage );
// Add our message queue to the hash table. Use our page reference
// (IHttpHandler) as the key.
m_executingPages.Add( HttpContext.Current.Handler, messageQueue );
// Wire up Unload event so that we can inject
// some JavaScript for the alerts.
executingPage.Unload += new EventHandler( ExecutingPage_Unload );
}
}
else
{
// If were here then the method has allready been
// called from the executing Page.
// We have allready created a message queue and stored a
// reference to it in our hastable.
Queue queue = (Queue) m_executingPages[ HttpContext.Current.Handler ];
// Add our message to the Queue
queue.Enqueue( sMessage );
}
}
// Our page has finished rendering so lets output the
// JavaScript to produce the alert's
private static void ExecutingPage_Unload(object sender, EventArgs e)
{
// Get our message queue from the hashtable
Queue queue = (Queue) m_executingPages[ HttpContext.Current.Handler ];
if( queue != null )
{
StringBuilder sb = new StringBuilder();
// How many messages have been registered?
int iMsgCount = queue.Count;
// Use StringBuilder to build up our client slide JavaScript.
sb.Append( "<script language='javascript'>" );
// Loop round registered messages
string sMsg;
while( iMsgCount-- > 0 )
{
sMsg = (string) queue.Dequeue();
sMsg = sMsg.Replace( "\n", "\\n" );
sMsg = sMsg.Replace( "\"", "'" );
sb.Append( @"alert( """ + sMsg + @""" );" );
}
// Close our JS
sb.Append( @"</script>" );
// Were done, so remove our page reference from the hashtable
m_executingPages.Remove( HttpContext.Current.Handler );
// Write the JavaScript to the end of the response stream.
HttpContext.Current.Response.Write( sb.ToString() );
}
}
}