Wednesday 28 July, 2010

Cancelling an Asynchronous PostBack in ASP.NET Ajax

The behavior of an Asynchronous postback is quiet similar to a synchronous postback. In an asynchronous model, all the server side events occur, as they do in a synchronous model. The Microsoft AJAX Library also raises client side events. However when the page is rendered, asynchronous postback renders only the contents of the update panel, where as in a synchronous postback, the entire page is recreated and sent back to the browser.
In one of the previous articles, I had shown how to cancel a Synchronous Postback using ASP.NET. In this article, we will see how to cancel an Asynchronous postback.
I assume you have some basic experience developing ASP.NET Ajax applications and have installed the ASP.NET Ajax Library and ASP.NET Control Toolkit. As of this writing, the toolkit version is Version 1.0.20229 (if you are targeting Framework 2.0, ASP.NET AJAX 1.0 and Visual Studio 2005) and Version 3.0.20229 (if targeting .NET Framework 3.5 and Visual Studio 2008). I have tested the sample using Version 3.0.20229 (targeting .NET Framework 3.5 and Visual Studio 2008); although I believe it will run with Version 1.0.20229 too.
The Application(Sys.Application) and PageRequestManager(Sys.WebForms.PageRequestManager) classes in the AJAX Library are prominent in raising events during the client life cycle of an ASP.NET AJAX Web page. If you have an update panel on your page, you can manipulate asynchronous postbacks by handling events exposed by the ‘PageRequestManager’ class. We will shortly see how we can use the client events of the ‘PageRequestManager’ class to provide functionality like cancelling a postback or aborting the current postback etc.
The process starts by subscribing to the ‘initializeRequest’ event of the ‘PageRequestManager’ class which gets raised during the initialization of the async postback. The event gives you an ideal place to cancel the currently executing asynchronous postback by using the ‘isInAsyncPostBack’ property of the ‘PageRequestManager’ class, to check whether an asynchronous postback is currently in progress. If it is, and the user performs another postback, you have the ability to cancel the new postback.
Note: ASP.NET Ajax can perform only one Asynchronous postback at a time.
Let us see this in action:
Step 1: Open Visual Studio > File > New Web Site > ASP.NET Web Site > Choose the location and language and click OK.
Step 2: Drag and drop a ScriptManager and an UpdatePanel to the page. In the update panel, drag and drop three buttons and a label control. The first button will cause the first postback, followed by the second one which will cause the second postback and the final button to abort the current postback. After registering the events, the code will look similar to the following:
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Button runat="server" Text="PostBackFirst" ID="btnPostF" onclick="btnPostF_Click"/>
<asp:Button runat="server" Text="PostBackSecond" ID="btnPostS" onclick="btnPostS_Click"/>
<asp:Button runat="server" Text="AbortPostBack" ID="btnAbort"/>
<asp:Label ID="Label1" runat="server" Text="Label">asp:Label>
ContentTemplate>
asp:UpdatePanel>
form>
body>
In the event handlers, add the following code:
C#
protected void btnPostF_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(4000);
Label1.Text = "PostBack 1 Completed";
}
protected void btnPostS_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(4000);
Label1.Text = "PostBack 2 Completed";
}
VB.NET
Protected Sub btnPostF_Click(ByVal sender As Object, ByVal e As EventArgs)
System.Threading.Thread.Sleep(4000)
Label1.Text = "PostBack 1 Completed"
End Sub
Protected Sub btnPostS_Click(ByVal sender As Object, ByVal e As EventArgs)
System.Threading.Thread.Sleep(4000)
Label1.Text = "PostBack 2 Completed"
End Sub
Here, we are introducing a delay of 4 seconds when a button click occurs. You can replace this with your processing code, like retrieving results from a database or a similar operation.
Step 3: To the element on the page, add the following javascript code:
<script type="text/javascript">
function pageLoad()
{
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(cancelPostBack);
}
function cancelPostBack(sender, args)
{
if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
{
alert('One postback at a time please');
args.set_cancel(true);
}
}
script>
As already explained in the introduction of this article, the code above demonstrates how to use and register the ‘initializeRequest’ event to determine whether an asynchronous postback is currently executing by using the ‘isInAsyncPostBack’ property. You can also cancel the current request by using the cancel property of the Sys.CancelEventArgs class.
Note: You can get the ID of the element which has initiated a new postback by ‘postBackElement’ property of the ‘Sys.WebForms.InitializeRequestEventArgs’ class. Something similar to: var ctrl = args.get_postBackElement() which returns the postback element that initiated the asynchronous postback.
Step 4: The last step left is to build functionality to abort the current postback by using the ‘abortPostBack()’ of the ‘PageRequestManager’ class. To do so, add the following code to the onClientClick() of the btnAbort as shown below:
<asp:Button runat="server" Text="AbortPostBack" ID="btnAbort"
OnClientClick="Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
alert('Postback Cancelled');"/>
The entire source will look similar to the following:
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>Cancel Async PostBacktitle>
<script type="text/javascript">
function pageLoad()
{
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(cancelPostBack);
}
function cancelPostBack(sender, args)
{
if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
{
alert('One postback at a time please');
args.set_cancel(true);
}
}
script>
head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Button runat="server" Text="PostBackFirst" ID="btnPostF"
onclick="btnPostF_Click"/>
<asp:Button runat="server" Text="PostBackSecond" ID="btnPostS"
onclick="btnPostS_Click"/>
<asp:Button runat="server" Text="AbortPostBack" ID="btnAbort"
OnClientClick="Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
alert('Postback Cancelled');"/>
<asp:Label ID="Label1" runat="server" Text="Label">asp:Label>
ContentTemplate>
asp:UpdatePanel>
form>
body>
html>
In order to test the functionality, follow these steps:
1. Run the application.
2. Click on ‘PostBackFirst’. Now immediately click on ‘PostBackSecond’. You will receive a message ‘One postback at a time please’. So our script has successfully discovered that there is an async postback currently in progress and hence does not allow the other.
3. Now to check how to abort a current async postback, click on either the ‘PostBackFirst’ or on ‘PostBackSecond’ and wait for 4 seconds. The default behavior is that when the current thread wakes up (remember we did Thread.Sleep()), a message is displayed ‘PostBack Completed’. Now click on the button again and this time, click on the ‘AbortPostBack’ button. You will see that the postback has aborted and the ‘PostBack Completed’ message is never displayed.
Now this was just a simple (call it lousy), but useful demonstration of how to cancel and abort async postbacks. I am sure you will be able to find out better implementations of this functionality in your applications. I would love to hear back from you if you implement in a practical scenario. I hope you liked the article and I thank you for viewing it.

No comments:

Post a Comment