Introduction
One very useful thing that I use in Windows applications is the raising of events between forms or sending messages from one form to another. I can then do something in the receiver form such as reload some data, fill some fields, do some calculations, etc. With Web Forms, it is not as straightforward a process because of the way Web applications work.
Background
I have seen several approaches to overcoming this limitation. The most popular is to use JavaScript to access an element in the Opener window and modify its value. Another way is to use the Server.Transfer
method and access the ViewState
from the previous page. However, this approach makes your Web application less secure because ViewState
hashing must be disabled to make this work. You subsequently have to leave the current page to display the new one. You can also use query strings to pass messages between forms and then auto-refresh the whole page, Opener or Child. I know there are many more approaches, but these are the most common.
Using the Code
I've worked with two approaches for this problem. The first is to use ASP.NET CallBacks and the other is to use Web Services and Ajax. Of course, these two approaches can be used together. In fact, I did not implement one purely Ajax+WS example. Anyway, both approaches use Javascript, so sorry to those who hate it just like me.
There are two versions of the sample code; both do the same thing. One uses VB.NET and the other one uses C#. The VB.NET version is a Web application project, so you must have installed the SP1 for VS 2005 or the update to support Web application projects. You can find both here. The C# code is a Website project. As I said, both samples do the same thing. Please note that this sample code is to show you how to implement or simulate Events between web forms, so do not take mind of the dirty way in which I implemented the Save data part.
Using CallBacks
To use Callbacks, you have to implement System.Web.UI.ICallbackEventHandler
in your class and implement two methods: RaiseCallbackEvent
and GetCallbackResult
.
For the Class
Partial Class ClientCallback
Inherits System.Web.UI.Page
Implements System.Web.UI.ICallbackEventHandler
The Methods
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _
Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
Public Function GetCallbackResult() _
As String Implements _
System.Web.UI.ICallbackEventHandler.GetCallbackResult
I know many of you have worked with this before. The trick to Raise the event in the Opener window is in the JavaScript code.
Child's JavaScript Code
function ReceiveCallBackResult(result)
{
document.getElementById("ResultsSpan").innerHTML = result;
window.opener.UserAddedEvent(result);
}
Parent's JavaScript Code
function UserAddedEvent(result)
{
document.getElementById("UserAdded").innerHTML = result;
ReloadUserList();
}
function ReloadUserList()
{
CallServer("", "");
}
As you can see, the JavaScript function called from the Child window invokes a function in the Opener that calls another. This makes a Callback to the server in the Opener window.
Using Ajax + Web Services
Using Ajax + Web Services is very similar to using Callbacks. The trick is in the JavaScript code. You have to make the Web Service call available from the JavaScript. To do this, you have to add one script reference to the Script Manager. Put the following in Page.Load
:
Dim TestWS As ServiceReference = New ServiceReference
TestWS.Path = "~/WSUsers.asmx"
objScriptManager.Services.Add(TestWS)
Next, add this JavaScript code to the element that you want to make the WS call:
onclick="AddUser();"
Now make the call to the WS:
function AddUser()
{
CallBacks.WSUsers.AddUser(document.getElementById(
"txtName").value,document.getElementById(
"txtAge").value,SucceededCallback);
}
This function is invoked when the call to the WS is finished:
function SucceededCallback(CallBackResult, eventArgs)
{
document.getElementById("ResultsSpan").innerHTML = CallBackResult;
window.opener.UserAddedEvent(CallBackResult);
}
As you can see, once the WS is called, the rest of the process is the same as in Callbacks. You can also make a call to a Web Service in the Opener window. An interesting approach is to send HTML as a response of the Web Service and put that HTML as the innerHTML
of an element.
Points of Interest
One limitation that we have using Callbacks is that we can only send and receive strings. So, if you want to send more than one value in the Callback, you will have to use separators of whatever you like. The same goes for the Callback response. I know many of you who have worked with Callbacks and Ajax + Web Services may think this code is a little bit disappointing. The interesting part of this code is that it puts all things together and gives some cool features. It is also easy to implement for beginners. I have not seen something like this for Web Forms, but I have to say that I didn't search very hard because I work too much with Windows Forms also. I use events between Forms too much, so I wanted to "port" this functionality to Web Forms. I would like to hear about some other approaches that you have used to simulate Events between Web Forms.
History
- 6 July, 2007 -- Original version posted: VB.NET Code V1.0, C# Code V1.0