ContentsThis article was originally published at http://aspnet.4guysfromrolla.com/articles/021104-1.aspx [^] on Feb 11, 2004.
Abstract
One of the useful features in a thick-client app that many programmers and end-users take for granted is message boxes. Due to their great business value, end-users will often expect message boxes in web pages as well. The problem is that they are created on the client, and therefore cannot be directly called from the server. Therefore unlike thick-client apps, it’s not as simple as using a single line of code to call a message box… but after this article it will be.
Top  The Business Benefit of Message BoxesOne of the useful features in a windows app that many programmers and end-users take for granted is message boxes. Two of the most common types are Alerts and Confirms.
A confirm message box requires the user to click "OK" to confirm their action and continue.
An alert message box presents a message to the user, and they simply must acknowledge it to continue.

Message boxes have great business benefit. They can make the site more useable because the user must first close the box before continuing, as opposed to sending the message to a label that could be ignored. For example an alert box can provide a practical way to inform the user that their data did not save to the database if there was a concurrency problem. A confirm box could provide a safety check to ensure that the user wanted to delete something. Message boxes can be a clean way to present information to your users, as opposed to weaving in labels throughout the page.
Perhaps most importantly, many clients like message boxes, have seen their success in thick client applications, and will take for granted that web application can handle these too.
As we mention the pros of message boxes, we need to also address two cons: First, message boxes may require an extra click from the user – as opposed to just browsing a label message without clicking anything. Second, because message boxes reside on the client, and the user can always disable client side scripting, the user could theoretically disable all your message boxes. However as allowing client side scripting is almost universal today, this isn't a big issue.
Top  Design RequirementsThere are two categories of situations to handle: (1) Moving from the Client to the Server (such as submitting a form), and (2) Moving from the Server back to the Client (such as returning from trying to save to the database). Furthermore, for maintainability, we want to abstract all the required code to a separate method. We can make this a static/shared method in a common "Utilities" class.
Top  The Technical ProblemThe problem with message boxes is that they are created on the client, and therefore cannot be directly called from the server. The server only takes the request, does stuff, and then returns a response. None of this intrinsically gives it the ability to "invade" your machine with potentially unwanted pop-up message boxes. Ultimately we need to have a client side script, such as JavaScript, call the message boxes.
Therefore unlike Windows Forms, it's not as simple as using a single line of code to call a message box... but after this article it will be.
Top  Implement: Client to ServerFirst let's start by showing how to add a box while moving from the client to the server. Once we have this code working, then we'll abstract it to the Utilities class.
Before ASP.Net, one way to do this would be make a regular HTML Input button and add a JavaScript onclick event to the button which calls an alert or confirm message box. Because a WebForm ultimately gets rendered as HTML, this is what we'll need to have the WebForm create. However rather than manually interweaving JavaScript into the ASPX page, we can use several built-in .Net methods.
Start by adding a WebControl Button that does some simply process on the server – such as setting the text property of a label. If we stopped here, the button would only generate the following HTML:
<input type="submit" name="BtnDelete" value="Delete" id="BtnDelete" /> But this is missing the JavaScript call. What we really want generated is something that includes the JavaScript, like:
<input type="submit" name="BtnDelete" value="Delete" id="BtnDelete" onclick="return confirm('Are you sure you want to delete?');" />In other words, we want to add another attribute and give it a value. Lucky for us, .Net provides just the method to do so... an Attributes.Add(key,value) method of the WebControl class. Therefore in the Page_Load event of the server, we could code the following:
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
If (Not Page.IsPostBack) Then
Me.BtnDelete.Attributes.Add("onclick", _
"return confirm('Are you sure you want to delete?');")
End If
End Sub
Because we only need to add this attribute the first time, we place the code in the Not Page.IsPostBack block. Also note the "return" keyword before the confirm. The confirm messagebox returns either a true or false. If the return keyword is omitted, then the value isn't returned, and the confirm box becomes useless.
Running the page and clicking the Button, you should see something like the screenshot below. In this example the Delete Button merely sets a label value, but that is sufficient enough to illustrate that something on the server has been run. Notice that that method only runs if you click okay to confirm.
Building off this success, we want to take it a step further and abstract the code to a separate Utilities class. To build the initial message box, we needed two things: (1) A WebControl Button, and (2) A message to display. We can easily pass both of these to a separate static/shared function like so:
Public Class Utilities
Public Shared Sub CreateConfirmBox(ByRef btn As WebControls.Button, _
ByVal strMessage As String)
btn.Attributes.Add("onclick", "return confirm('" & strMessage & "');")
End Sub
End Class
We could then call it from within the Page_Load event of the WebForm, passing both a reference to the button as well as the message:
Utilities.CreateConfirmBox(Me.BtnDeleteUtil, _
"Are you sure you want to delete (this uses the Utilities Class)?")
Top  Implement: Server to ClientBesides having the user confirm that they wanted to do an action, we may also want to alert them of results based off of processing on the server. For example, say that due to concurrency issues, their data wasn't saved. The question becomes, coming back from the server to the client, how would we alert the user with a message box?
Traditionally we would do this with JavaScript in the html of the page by creating an onload event that generated a message box. However like the previous case, .Net provides us additional methods to handle all this from the Code Behind.
What we want to do is register a client script block with the ASPX page. More specifically, we want this to run when the page starts up on the client. Again it's our lucky day... .Net provides a RegisterStartupScript method for that very purpose.
Because we only want this Message Box to run from a specific event, such as clicking a button, we'll add the code to that specific event handler:
Private Sub BtnSave_Click(ByVal sender As System.Object,
_ByVal e As System.EventArgs) Handles BtnSave.Click
'Generates the message:
Dim strMessage As String
If (Me.CheckBox1.Checked()) Then
strMessage = "The data was saved."
Else
strMessage = "The data was NOT saved."
End If
'finishes server processing, returns to client.
Dim strScript As String = ""
If (Not IsClientScriptBlockRegistered("clientScript")) Then
Page.RegisterStartupScript("clientScript", strScript)
End If
End Sub
This code first generates the message by checking field values (in this case if a CheckBox1 was checked or not) and building the message appropriately. However note that the message could be generated from any server-side process, such as the return value of a business object.
Once we have the message, we can build the JavaScript block. This includes (1) the <script></script> tags, and (2) the alert('...') method call. Finally we check if the block has already been registered to the page (passing in an identifying key "clientScript"). We only register it if it hasn't already been done. The RegisterStartupScript() method requires passing in the identifying key and the script string we built.
In the screen below, the user has selected the checkbox and then clicked the save button. The server then generates the necessary JavaScript block, registers it, and displays it upon returning the page to the client.

Like the previous sample, we can also abstract this to a Utilities class. We needed a Page reference, and a message to display, and we can pass both of those to another Utilities method:Public Class Utilities<BR>
Public Shared Sub CreateMessageAlert(ByRef aspxPage As _
System.Web.UI.Page, ByVal strMessage As String, ByVal strKey As String)
Dim strScript As String = ""
If (Not aspxPage.IsClientScriptBlockRegistered(strKey)) Then
aspxPage.RegisterStartupScript(strKey, strScript)
End If
End Sub
End Class
Here we've passed by reference the WebForm, a message, and some unique identifying key (which could be anything). The method builds the script block by adding the <script> tags and alert('') call. It then checks if the script is registered and adds appropriately. Notice that this method doesn't need to return anything because it's directly affecting the page itself.
The original page could call this method like so:Private Sub BtnSaveUtil_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles BtnSaveUtil.Click
'Generates the message:
Dim strMessage As String
If (Me.CheckBox1.Checked()) Then
strMessage = "The data was saved."
Else
strMessage = "The data was NOT saved."
End If
'Call separate class, passing page reference, to register Client Script:
Utilities.CreateMessageAlert(Me, strMessage, "strKey1")
End Sub Notice that we still need to generate the message. We also pass just a dummy string "strKey1" to the method to provide for the key.
Top  Extending the FunctionalityWe could easily extend the two cases mentioned in this article. For example, we could add additional JavaScript besides just message box code, such as using document.location = 'myPage.aspx' to redirect the page, or document.forms[0].submit() to re-submit the page and thereby refresh its data. The sky is the limit!
Top  Why we didn't do other implementationsTo solidify the concepts in this article, it may help to understand why we didn't create message boxes with the following ways:
1 - Have the page Response.Write out the JavaScript code, such as an alert box: This would create a blank screen because first it sends just the message box code, waits until the user closes that box, and then continues with the remaining content. This blank screen can be considered unattractive.
2 – Hardcode JavaScript like the "good old days": This would become a nightmare to maintain by weaving together the aspx page and the code behind page.
Both of these ways also are harder to abstract out to a separate class. They also require manually writing redundant code such as the <script> tags, when the only "new" thing we care about is the message to send.
Top  ConclusionWe've seen how to create a separate class that contains static/shared members which the WebForm can call to create MessageBoxes. This article has addressed the two most common cases: (1) Confirming before running an event on the server and (2) Alerting the user about something after finishing a server process. At the end of the day, this gives us one more card to play in building usable web applications.
Top 
About
Tim Stall
| Tim Stall is a Chicago-based technical consultant for Computer Sciences Corporation (www.csc.com), a leading global IT services company. In addition to his expertise in Microsoft.Net development projects and enterprise architecture, Tim's .Net experience includes, writing technical publications, leading internal training, and having MCAD certification. His blog is at http://timstall.dotnetdevelopersjournal.com. |
Click here if you want to know more about
Tim Stall.
Other articles that may interest you
|