Chapter 10: ASP.NET AJAX
Chapter 19: ASP.NET AJAX
So, all the texts start this off at talking about the scenario when updating part of a web page is desired, which is referred as asynchronous HTTP request.
The new ASP.NET AJAX server controls that come with ASP.NET 3.5:
ASP.NET AJAX Server Control | Description |
ScriptManager | |
ScriptManagerProxy | |
Timer | |
UpdatePanel | |
UpdateProgress | A control that allows you to display a visual element to the end user to show that a partial-page postback is occurring to the part of the page making the update. This is an ideal control to use when you have long-running AJAX updates. |
ScriptManager
ScriptManager is a requirement for most Ajax functionality to operate correctly. It serves as the bridge between the client page and the Ajax Framework.
It takes care of:
- registering the correct JavaScript files that are used in the browser;
- marshalling the messages back and forth between the server and the client for the partial page rendering process;
- handling interaction with your web site for things like Web Services and the ASP.NET application services like membership, roles, and profile.
Let's create a web page with only ScriptManager:
Create a new Web application project, and add a new web form item, then drag a ScriptManager control onto the page:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Only ScriptManager</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
</div>
</form>
</body>
</html>
It outputs(a bit different from the book, in that I am using framework 4.0 instead of 3.5):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
Only ScriptManager
</title></head>
<body>
<form method="post" action="WebForm1.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTY0Mzg3MTY0M2RkFL27ljtYCk/Isww82JSf+5d7BthvQonz7MiYxWhnVlw=" />
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<script src="/WebResource.axd?d=0gLFhBDIyhK-EeSqqWToW2Gw7pkexkCF2rGqpQEkA-nuW8WUCmrkT_eUGLHrQMoPdkfmhgCy_pdMtn1MZYAnBxGxxLWTO4DINQSXfCDiSQQ1&t=634773918900000000" type="text/javascript"></script>
<script src="/ScriptResource.axd?d=hI45Ku7hBa45ih5Sild8Y5WXhZJ0UzTCmvIHttWoQVSNI2t5pQCho68hoW2FibkZVkLUplb4-XYc-2DuiovkBcMCJ5rsA6FkZcv83sbhtW4Vx4kifZzXBp-b5scOrwg8Ry-IF7bSMT_fqQh7oXEoUZ1NgjWwAclq8G2hDf7l_TLtzYMlPHvR75oaqeSmibpp0&t=6119e399" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.');
//]]>
</script>
<script src="/ScriptResource.axd?d=BKwqA_yPGe3Zp_sXNpw5ERCUDbaL01FH-OrxiMn3vEtIQ8Ee0G6XWGBTyGW4Ah6Pca5TaeDZ9q4Q-BkIy3SO2Xebl6OZ8eLKY_5rm6ZmzSAf4b9swZu_6JjUFCyrTkhVAZjrg7cGG7m3dRZWiv6DfubRtu42uFu2Zf_20bOaCe5H_dp0nS9OhZ5iCx6Ac4hD0&t=6119e399" type="text/javascript"></script>
<div>
<script type="text/javascript">
//<![CDATA[
Sys.WebForms.PageRequestManager._initialize('ScriptManager1', 'form1', [], [], [], 90, '');
//]]>
</script>
</div>
</form>
</body>
</html>
The script nodes are actually the library files, they are dynamically registered and available through the HTTP handler provided through the ScriptResource.axd handler.
Let's take one step further, looking into the resources it registers:
Properties of ScriptManager:
Property | Value |
AllowCustomErrorsRedirect | |
AsyncPostBackErrorMessage | |
EnablePageMethods | |
EnablePartialRendering | |
Scripts | |
Services | Allows you to define Web Services that are accessible by your client side pages. |
When ScriptManagerProxy comes in play
You can only have one ScriptManager in a page, you can't add another one in a content page that uses your master page with the ScriptManager.
What if you want to modify the ScriptManager control's behavior just for one specific content page?
In such case you need to add a ScriptManagerProxy control to the content page, to serve as a bridge between the content page and the ScriptManager in the master page.
UpdatePanel
The UpdatePanel control is a key component in creating flicker-free pages, which is a way to trigger a partial page postback and update only the portion of the page. It is a container control, you simply wrap the control around content you want to update.
- Everything within the <ContentTemplate> section will be pull forth and back between client and server.
- The ways to initiate the asynchronous postback:
- Be default, only its inner contents are refreshed by other server controls defined within the <ContentTemplate> element.
- By using <Triggers> element, you tie up a page event to cause the postback to occur. That means you can move your button out of the <UpdatePanel> control.
- Be default, only its inner contents are refreshed by other server controls defined within the <ContentTemplate> element.
- The <Triggers> section can contain two possible controls: AsyncPostBackTrigger and PostBackTrigger. The PostBackTrigger control will cause a full-page postback, whereas the AsyncPostBackTrigger control will cause only an asynchronous page postback.
- With <Triggers> element, you can link a Timer control up with UpdatePanel, to make the postback occur at secific intervals in time. Refer to the code in page 335 in [Begin ASP.NET 3.5].
- You can use multiple UpdatePanel controls within a single page:
- By default, all UpdatePanel controls on a single page update with each asynchronous postback that occurs, even if you have a UpdatePanel not in linkage with (via <Trigger> element) any button out of it. Because UpdateMode property's efault value is Always.
- You can control this behavior, by switching the UpdatePanel's UpdateMode property, between Always and Conditional.
- By default, all UpdatePanel controls on a single page update with each asynchronous postback that occurs, even if you have a UpdatePanel not in linkage with (via <Trigger> element) any button out of it. Because UpdateMode property's efault value is Always.
Page History
ScriptManager has a bundle of properties/methods to help you keep track of navigation history, since ASP.NET 3.5 SP1. They are:
- EnableHistory
- OnNavigate
- AddHistoryPoint
- IsNavigating
- IsInAsyncPostBack
Refer to the code in page 904 in [Professional ASP.NET 3.5 SP1].
Script Combining
By default, ASP.NET AJAX pages sometimes download a number of different scripts for the page that is being viewed. When they are being downloaded separately, you will find that the performance is worse overall for the page. ASP.NET 3.5 SP1 introduces the capability to combine the scripts into a single request and response. This is termed script combining.
The trick is figuring out what scripts need to be combined as it isn't always that apparent. For this reason, there is a CodePlex project out there on the Internet that provides you a server control that can be placed on the page to help you figure this out. The server control, ScriptReferenceProfiler, provides you with a list of the scripts that are required for the page. This control can be found at the following address:
http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=13356
Work with Web Service
It is easy to call Web Service with ScriptManager. Refer to the code in page 345 in [Begin ASP.NET 3.5].
You can get some flavor of the JavaScript framework comes with ASP.NET from this sample. You will see some DOM manipulating functions like jQuery:
$addHandler($get('btnSayHello'), 'click', HelloWorld);
The $addHandler is actually a shortcut to the addHandler method of the Sys.UI.DomEvent class defined in the Ajax Framework. You can use it to register event handlers for specific events of the objects in your pages.
Just like $get, the $addHandler method is a convenient shortcut that works cross-browser to register events.
The cool thing about $get and $addHandler is that you can use them in any site. All you need to do is include the ScriptManager control in a master or content page and you're ready to use the client-side framework. You don't need to use Web Services or other Ajax-related controls in your page to make this work.
--------------------------------------------------------
When you create a new master page from the Add New Item dialog, in addition to an option for a Master Page, there is also an option to add an AJAX Master Page. This option creates the page
<%@ Master Language="VB" %>
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>