Chapter 25 How to use AJAX Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 1 Objectives Applied Use the ASP.NET AJAX server controls to develop simple ASP.NET AJAX applications. Knowledge Distinguish between a normal HTTP request and an AJAX HTTP request. In general terms, describe the Microsoft AJAX Library and the ASP.NET AJAX controls. Describe the use of these ASP.NET AJAX controls: ScriptManager, UpdatePanel, UpdateProgress, and Timer. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 2 Standard request and response cycle Client HTTP request: The browser requests a page. Server Browser Web server HTTP response: The server returns the requested page and the page is loaded. Browser Murach’s ASP.NET 3.5/C#, C25 Web server © 2008, Mike Murach & Associates, Inc. Slide 3 AJAX-enabled request and response cycle AJAX HTTP request: The browser requests updated information for a page. Client Server Browser Web server AJAX HTTP response: The server returns the requested information and the page is updated. Browser Murach’s ASP.NET 3.5/C#, C25 Web server © 2008, Mike Murach & Associates, Inc. Slide 4 AJAX concepts A rich Internet application (RIA) is an application that is displayed in a web browser, but has some of the features of a desktop application such as an enhanced user interface and quick response time. Asynchronous JavaScript and XML (AJAX) is one way to build a RIA. Each time a standard HTTP request and response cycle is performed, the entire page is returned from the server and the page is loaded into the browser. With an AJAX HTTP request and response cycle, the browser can request just the information it needs to update the page. Then, the updated information that’s returned from the server can be used to update the page without having to reload it. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 5 The architecture of AJAX Web browser Web page DOM Events 5 Web server 1 JavaScript and XMLHttpRequest Murach’s ASP.NET 3.5/C#, C25 2 4 Application server 3 © 2008, Mike Murach & Associates, Inc. Slide 6 How AJAX works The web page that is downloaded from the web server contains HTML, CSS, and JavaScript. The web browser uses the HTML and CSS to build the Document Object Model (DOM), which is an object-oriented representation of the content in the page. JavaScript is used to run code when events occur in the web page. JavaScript also has access to the DOM to determine the state of controls on the page and to make changes to the DOM that will be shown to the user. The XMLHttpRequest object that’s built into the web browser is used to communicate with the web server. JavaScript is used to access the functionality of the XMLHttpRequest object. For most requests, JavaScript Object Notation (JSON) is now used to send data back to the web browser Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 7 How AJAX updates the contents of a web page 1. An event happens on the web page. This can be the user moving the mouse, clicking a button, or changing a field or a timer going off. This event triggers JavaScript code to execute. 2. JavaScript prepares a request and sends it to the web server. The request contains information about the event and the current state of the controls on the web page. 3. The server receives the data and processes it. Although processing can take place on the client, some actions, such as database access, must happen on the server. 4. The server prepares a response and sends it back to the browser. The response contains the updated state of the controls on the web page. 5. JavaScript parses the response and uses the data it contains to update the contents of the web page by modifying objects in the DOM. The browser then updates the user’s screen. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 8 The architecture of ASP.NET AJAX Web browser Web page DOM Events Web server ASP.NET application server JavaScript Microsoft AJAX Library Murach’s ASP.NET 3.5/C#, C25 ASP.NET AJAX server controls ASP.NET AJAX Control Toolkit © 2008, Mike Murach & Associates, Inc. Slide 9 Components of ASP.NET AJAX Microsoft AJAX Library ASP.NET AJAX server controls ASP.NET AJAX Control Toolkit Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 10 How ASP.NET AJAX works Microsoft developed a set of extensions to ASP.NET 2.0 that provided AJAX support. These extensions were incorporated as built-in features of ASP.NET 3.5 and Visual Studio 2008. ASP.NET uses an asynchronous postback to perform a partialpage update. During an asynchronous postback, the view state of the web page is sent to the server, which processes the request and sends back the new view state of the controls being updated. The ASP.NET AJAX server controls enclose other ASP.NET server controls to make them AJAX-enabled. These controls can then be updated using an asynchronous postback. A single page can have one or more groups of AJAX-enabled controls that can be updated independently or simultaneously. Server controls that are not AJAX-enabled will still trigger a full postback that causes the entire page to be reloaded. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 11 Features of the Microsoft AJAX Library Cross-browser compatibility Debugging JavaScript type extensions Globalization and localization Event handling Networking Classes and namespaces JSON serialization Inheritance and interfaces Components Reflection Partial-page updates Exception handling Application services Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 12 ASP.NET AJAX server controls ScriptManager ScriptManagerProxy UpdatePanel UpdateProgress Timer Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 13 The ScriptManager control You can only have one ScriptManager control on a page. This includes master and content pages. If there is more than one ScriptManager control on a page, an Invalid Operation exception will be generated. The ScriptManager control can also be used to load and manage additional JavaScript files and to register web services so they can be accessed by JavaScript code on the client through a web service proxy. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 14 The ScriptManagerProxy control The ScriptManagerProxy control lets you load JavaScript files and register web services. This control can be used: in a content page if the master page contains a ScriptManager control in a user control that will be used on pages that contain a ScriptManager control Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 15 The UpdatePanel control The UpdatePanel control is a container control that holds other server controls that will be updated during an asynchronous postback. All controls inside an UpdatePanel control will be updated at the same time. A page can contain multiple UpdatePanel controls, each with a different set of controls. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 16 The UpdateProgress control You can use the UpdateProgress control to visually indicate that an asynchronous postback is in progress and that the user should wait until it’s completed before doing anything else on the page. This is useful when an asynchronous postback will take a few seconds or more to complete. The Timer control When one or more UpdatePanel controls need to be updated automatically, you can use the Timer control to trigger partial-page updates at a set time interval. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 17 Common ASP.NET AJAX Control Toolkit controls Accordion PagingBulletedList Animation PopupControl Calendar RoundedCorners CollapsiblePanel Slider DragPanel SlideShow DropShadow TabContainer HoverMenu TextBoxWatermark ModalPopup ToggleButton NumericUpDown Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 18 Web sites related to the ASP.NET AJAX Control Toolkit www.asp.net/ajax/ajaxcontroltoolkit/samples/ www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 19 Common attributes of the ScriptManager control AsyncPostBackTimeout EnablePageMethods EnableScriptGlobalization EnableScriptLocalization IsInAsyncPostBack LoadScriptsBeforeUI The aspx code for a ScriptManager control <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 20 The aspx code for a ScriptManager control that registers scripts <asp:ScriptManager ID="ScriptManager1" runat="server"> <Scripts> <asp:ScriptReference Path="~/Scripts/SampleScript.js" /> <asp:ScriptReference Assembly="SampleAssembly" Name="SampleAssembly.SampleScript.js" /> </Scripts> </asp:ScriptManager> The aspx code for a ScriptManager control that registers a web service <asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/Services/SampleService.asmx" /> </Services> </asp:ScriptManager> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 21 A content page with a ScriptManagerProxy control Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 22 The aspx code for the ScriptManagerProxy control <asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server"> </asp:ScriptManagerProxy> The aspx code for a ScriptManagerProxy control that registers scripts <asp:ScriptManagerProxy ID="ScriptManager1" runat="server"> <Scripts> <asp:ScriptReference Path="~/Scripts/SampleScript.js" /> <asp:ScriptReference Assembly="SampleAssembly" Name="SampleAssembly.SampleScript.js" /> </Scripts> </asp:ScriptManagerProxy> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 23 The aspx code for a ScriptManagerProxy control that registers a web service <asp:ScriptManagerProxy ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="~/Services/SampleService.asmx" /> </Services> </asp:ScriptManagerProxy> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 24 Two attributes of the UpdatePanel control Attribute Description ChildrenAsTriggers Determines if the controls in a panel are treated as triggers that cause the content of the panel to be updated when a control causes a postback. The default is True. UpdateMode Determines when the content of a panel is updated (Always or Conditional). A nested UpdatePanel control will always be updated when its parent UpdatePanel control is updated. The default is Always. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 25 The starting aspx code for an UpdatePanel control <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> </ContentTemplate> </asp:UpdatePanel> The aspx code for an UpdatePanel control that specifies triggers <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Button ID="Button2" runat="server" Text="Add" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" /> <asp:PostBackTrigger ControlID="Button2" /> </Triggers> </asp:UpdatePanel> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 26 Controls that have compatibility issues with the UpdatePanel control GridView DetailsView TreeView Menu FileUpload Login PasswordRecovery ChangePassword CreateUserWizard Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 27 A Timer control in Design view Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 28 Two attributes of the Timer control Attribute Interval Enabled Murach’s ASP.NET 3.5/C#, C25 Description Determines how often in milliseconds the control will trigger an asynchronous postback. The default value is 60,000 milliseconds (60 seconds). Determines whether a postback occurs when the time specified by the Interval attribute elapses. The default is True. © 2008, Mike Murach & Associates, Inc. Slide 29 The aspx code for an UpdatePanel control with a Timer control <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Timer ID="Timer1" runat="server" Interval="10000"> </asp:Timer> </ContentTemplate> </asp:UpdatePanel> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 30 An UpdateProgress control in Design view Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 31 Three attributes of the UpdateProgress control Attribute DynamicLayout Description Determines whether space is allocated on the page for the content of the control when it isn’t displayed. The default is True. DisplayAfter Determines how long in milliseconds after the asynchronous postback has started to display the content. The default is 500 milliseconds (0.5 seconds). AssociatedUpdatePanelID The ID of the UpdatePanel control that the control is associated with. Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 32 The aspx code for an UpdatePanel control with an UpdateProgress control <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> Please wait. The update is in progress. </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 33 The Shout Box application Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 34 The ShoutItem.cs file using System; public class ShoutItem { public string UserName; public DateTime Timestamp; public string Comment; } Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 35 The ShoutItemList.cs file using System; using System.Collections.Generic; using System.Text; public class ShoutItemList { private List<ShoutItem> shoutList = new List<ShoutItem>(); private void Purge(){ DateTime purgeTime = DateTime.Now; purgeTime = purgeTime.AddMinutes(-3); int i = 0; while (i < shoutList.Count){ if (shoutList[i].Timestamp <= purgeTime) shoutList.RemoveAt(i); else i += 1; } } Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 36 The ShoutItemList.cs file (cont.) public void Add(ShoutItem shout){ Purge(); System.Threading.Thread.Sleep(2000); shoutList.Insert(0, shout); } public string Display(){ Purge(); StringBuilder shoutBoxText = new StringBuilder(); if (shoutList.Count > 0){ shoutBoxText.AppendLine("<dl>"); foreach (ShoutItem shout in shoutList){ shoutBoxText.Append( "<dt>" + shout.UserName); shoutBoxText.Append(" ("); shoutBoxText.Append( shout.Timestamp.ToShortDateString()); shoutBoxText.AppendLine(")</dt>"); shoutBoxText.AppendLine("<dd>" + shout.Comment + "</dd>"); } Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 37 The ShoutItemList.cs file (cont.) shoutBoxText.AppendLine("</dl>"); } return shoutBoxText.ToString(); } } Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 38 The Default.aspx file: Shout Box application <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!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>Chapter 25: Product List with AJAX Shout Box </title> <style type="text/css"> .style1 {width: 100px;} .style2 {width: 200px;} .style3 {width: 80px;} .style4 {width: 390px;} .style5 {width: 10px;} .style6 {width: 290px;} .style7 {width: 75px;} .style8 {width: 225px;} </style> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 39 The Default.aspx file (cont.) <link href="ShoutBox.css" rel="stylesheet" type="text/css" /> </head> <body> <form id="form1" runat="server"> <div> <asp:Image ID="Image1" runat="server" ImageUrl="~/Images/banner.jpg" /> <br /><br /> Choose a category:&nbsp; <asp:DropDownList ID="Category" runat="server" AutoPostBack="True" Width="130px" DataSourceID="SqlDataSource1" DataTextField="LongName" DataValueField="CategoryID"> </asp:DropDownList> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 40 The Default.aspx file (cont.) <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString= "<%$ ConnectionStrings:HalloweenConnectionString %>" SelectCommand="SELECT [CategoryID], [LongName] FROM [Categories] ORDER BY [LongName]"> </asp:SqlDataSource> <br /><br /> <table> <tr> <td class="style4" valign="top"> <asp:DataList ID="DataList1" runat="server" DataSourceID="SqlDataSource2" BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px" CellPadding="3" ForeColor="Black" GridLines="Vertical"> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 41 The Default.aspx file (cont.) <HeaderTemplate> <table> <tr> <td class="style1">ID</td> <td class="style2">Product</td> <td class="style3" align="right"> Unit Price</td> <td class="style3" align="right"> On Hand</td> </tr> </table> </HeaderTemplate> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 42 The Default.aspx file (cont.) <ItemTemplate> <table><tr> <td class="style1"> <asp:Label ID="ProductID" runat="server" Text='<%# Eval("ProductID") %>'> </asp:Label></td> <td class="style2"> <asp:Label ID="ProductName" runat="server" Text='<%# Eval("Name") %>'> </asp:Label></td> <td class="style3" align="right"> <asp:Label ID="UnitPrice" runat="server" Text= '<%# Eval("UnitPrice", "{0:c}") %>'> </asp:Label></td> <td class="style3" align="right"> <asp:Label ID="OnHand" runat="server" Text='<%# Eval("OnHand") %>'> </asp:Label></td> </tr></table> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 43 The Default.aspx file (cont.) </ItemTemplate> <AlternatingItemStyle BackColor="#CCCCCC" /> <HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" /> </asp:DataList></td> <td class="style5"></td> <td class="style6" valign="top"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> Here's what everyone is saying:<br /><br /> <asp:UpdatePanel ID="ShoutBoxPanel1" runat="server"> <ContentTemplate> <asp:Label ID="lblShoutBox" runat="server"></asp:Label> <asp:Timer ID="Timer1" runat="server" Interval="5000"> </asp:Timer> </ContentTemplate> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 44 The Default.aspx file (cont.) <Triggers> <asp:AsyncPostBackTrigger ControlID="btnAddShout" EventName="Click" /> </Triggers> </asp:UpdatePanel><br /> <asp:UpdatePanel ID="ShoutBoxPanel2" runat="server" UpdateMode="Conditional"> <ContentTemplate> <table> <tr> <td class="style7">Name:</td> <td class="style8"> <asp:TextBox ID="txtUserName" runat="server" MaxLength="15" Width="100px"></asp:TextBox></td> </tr> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 45 The Default.aspx file (cont.) <tr> <td class="style7">Shout:</td> <td class="style8"> <asp:TextBox ID="txtShout" runat="server" MaxLength="255" Width="220px"></asp:TextBox></td> </tr> </table> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="Name is required." ControlToValidate="txtUserName" Display="Dynamic"> </asp:RequiredFieldValidator> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 46 The Default.aspx file (cont.) <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="Shout is required." ControlToValidate="txtShout" Display="Dynamic"> </asp:RequiredFieldValidator> <asp:Button ID="btnAddShout" runat="server" Text="Add Shout" /> <asp:UpdateProgress ID="UpdateProgress1" runat="server" DynamicLayout="False"> <ProgressTemplate> <img src="Images/spinner.gif" alt="Please Wait" style="vertical-align: middle" /> Uploading Comment... </ProgressTemplate> </asp:UpdateProgress> </ContentTemplate> </asp:UpdatePanel> </td> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 47 The Default.aspx file (cont.) </tr> </table> <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString= "<%$ ConnectionStrings:HalloweenConnectionString %>" SelectCommand="SELECT [ProductID], [Name], [UnitPrice], [OnHand] FROM [Products] WHERE ([CategoryID] = @CategoryID) ORDER BY [ProductID]"> <SelectParameters> <asp:ControlParameter Name="CategoryID" Type="String" ControlID="Category" PropertyName="SelectedValue" /> </SelectParameters> </asp:SqlDataSource> </div> </form> </body> </html> Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 48 The ShoutBox.css file #ShoutBoxPanel1 { height: 300px; border: solid 1px black; overflow: auto; } #ShoutBoxPanel1 dl { margin-top: 0px; } Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 49 The Default.aspx.cs file: Shout Box application using using using using using using using using using using using System; System.Configuration; System.Data; System.Linq; System.Web; System.Web.Security; System.Web.UI; System.Web.UI.HtmlControls; System.Web.UI.WebControls; System.Web.UI.WebControls.WebParts; System.Xml.Linq; Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 50 The Default.aspx.cs file (cont.) public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ShoutItemList shoutBox; if (Application["ShoutBox"] == null) { shoutBox = new ShoutItemList(); Application.Add("ShoutBox", shoutBox); } else { shoutBox = (ShoutItemList) Application["ShoutBox"]; lblShoutBox.Text = shoutBox.Display(); } if (ScriptManager1.IsInAsyncPostBack != true) txtUserName.Focus(); } Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 51 The Default.aspx.cs file (cont.) protected void btnAddShout_Click(object sender, EventArgs e) { ShoutItem shout = new ShoutItem(); shout.UserName = txtUserName.Text; shout.Comment = txtShout.Text; shout.Timestamp = DateTime.Now; Application.Lock(); ShoutItemList shoutBox = (ShoutItemList) Application["ShoutBox"]; shoutBox.Add(shout); Application.UnLock(); lblShoutBox.Text = shoutBox.Display(); txtShout.Text = ""; txtShout.Focus(); } } Murach’s ASP.NET 3.5/C#, C25 © 2008, Mike Murach & Associates, Inc. Slide 52