{"id":258,"date":"2007-05-01T00:00:00","date_gmt":"2007-05-01T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/enhance-your-website-with-asp-net-ajax-extensions\/"},"modified":"2021-05-17T18:35:06","modified_gmt":"2021-05-17T18:35:06","slug":"enhance-your-website-with-asp-net-ajax-extensions","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/enhance-your-website-with-asp-net-ajax-extensions\/","title":{"rendered":"Enhance your Website with ASP.NET AJAX Extensions"},"content":{"rendered":"<div id=\"pretty\">\n<p class=\"start\">AJAX (Asynchronous JavaScript and XML) is arguably one of the most hyped technology acronyms around. The primary advantage of using AJAX is that page refreshes can be minimized, allowing users to get the information they need quickly and easily through a more rich and functional interface. Ajax accomplishes this by using JavaScript and an <b>XmlHttp<\/b> object to send data asynchronously from the browser to the Web server and back. So, although AJAX has a lot of marketing-hype surrounding it, the benefits it offers can&#8217;t be denied.<\/p>\n<p>Microsoft&#8217;s ASP.NET AJAX Extensions provide developers with a quick and simple way to add AJAX functionality into any ASP.NET Website, without requiring in-depth knowledge of JavaScript or other AJAX technologies. This article will demonstrate how you can add AJAX capabilities into a new or existing Website by using a new ASP.NET AJAX server-side control called the <b>UpdatePanel<\/b>. You&#8217;ll see how the <b>UpdatePanel<\/b> control can be used to allow portions of a page to be updated without requiring the entire page to be posted back to the server and reloaded in the browser. Additional topics covered include:<\/p>\n<ul>\n<li>The role of the <b>ScriptManager <\/b>control  <\/li>\n<li>Nesting <b>UpdatePanel<\/b> controls  <\/li>\n<li>Triggering asynchronous requests  <\/li>\n<li>Providing progress indicators to end users  <\/li>\n<li>Interacting with the <b>UpdatePanel<\/b> on the client-side, using the <b>PageRequestManager<\/b> class. <\/li>\n<\/ul>\n<p>Let&#8217;s get started by discussing how to get the ASP.NET AJAX Extensions installed and configured.<\/p>\n<h3>Installing the ASP.NET AJAX extensions <\/h3>\n<p>Before you can use the ASP.NET AJAX <b>UpdatePanel<\/b> control you need to install the ASP.NET AJAX Extensions, available from <a href=\"http:\/\/ajax.asp.net\/\">http:\/\/ajax.asp.net\/<\/a>, on your development machine. Once installed, a new Website template titled &#8220;ASP.NET AJAX-Enabled Website&#8221; will appear when you first create a new Website using Visual Studio .NET 2005 or Web Developer Express. Select this template when you want to add ASP.NET AJAX functionality into Web pages. <\/p>\n<p>The ASP.NET AJAX Extensions rely upon special HTTP handlers and modules to handle and respond to asynchronous requests sent from a browser. By creating a new ASP.NET AJAX Website in Visual Studio .NET, a web.config file will automatically be created that contains references to a ScriptResource.axd handler as well as a <b>ScriptModule<\/b> module. The <b>ScriptResource<\/b> handler dynamically loads JavaScript files into pages that leverage AJAX features while <b>ScriptModule<\/b> manages HTTP module functionality that is related to request and response messages. <\/p>\n<p>If you&#8217;d like to upgrade an existing Website and add ASP.NET AJAX functionality into it you&#8217;ll need to ensure that you manually update your site&#8217;s web.config file with the proper entries. The easiest way to do this is to create a new ASP.NET AJAX-Enabled Website (as mentioned earlier) and then copy the AJAX-specific portions of web.config to your original web.config file. You&#8217;ll of course need to ensure that the ASP.NET AJAX Extensions are also installed on your production server before deploying the updated site.<\/p>\n<h3>Adding AJAX functionality into ASP.NET Web Forms <\/h3>\n<p>Before the ASP.NET AJAX Extensions were released, developers had to rely on custom AJAX libraries to AJAX-enable a Web site. While these libraries were quite powerful and worked in cross-browser scenarios, they often required a familiarity with JavaScript, and even XML or Web Service technologies. Some of the frameworks were\/are susceptible to CSRF (Cross Site Request Forgery) attacks, whereby a hacker could hi-jack AJAX messages and potentially steal information. Fortunately, the ASP.NET AJAX Extensions offer a secure AJAX framework that includes a new server control called the <b>UpdatePanel<\/b> that hides JavaScript complexities. <\/p>\n<p>The <b>UpdatePanel<\/b> control allows you to focus on the functionality of your application rather than on programming and understanding AJAX-specific technologies. It performs asynchronous postback operations that update a portion of a page rather than the entire page itself. This technique is often referred to as &#8220;<i>partial-page updates<\/i>&#8220;. The <b>UpdatePanel<\/b> control works by intercepting postback requests triggered by the page and converting them into asynchronous postback calls, which are then sent to the server using the browser&#8217;s <b>XmlHttp<\/b> object. It relies on client-side scripts managed by the ASP.NET AJAX framework to perform this asynchronous functionality.<\/p>\n<p>Before using the <b>UpdatePanel<\/b> control you must first add into your page an important ASP.NET AJAX control, called the <b>ScriptManager<\/b>. The <b>ScriptManager<\/b> handles loading all of the necessary client-side scripts that are required by the <b>UpdatePanel<\/b> and other AJAX controls in order to make asynchronous AJAX calls. You can drag a <b>ScriptManager<\/b> control onto a page from the VS.NET toolbox or add it directly into the source code as shown next:<\/p>\n<pre>&lt;asp:ScriptManager id=\"ScriptManager1\"\" runat=\"server\" \/&gt;\n<\/pre>\n<p>Once a <b>ScriptManager<\/b> control is added, an <b>UpdatePanel<\/b> control can then be defined in the page. The <b>UpdatePanel<\/b> acts as a container in much the same way as the standard ASP.NET Panel control. However, content embedded within the <b>UpdatePanel<\/b> is wrapped within a template named <b>ContentTemplate<\/b>. Any content placed within the <b>ContentTemplate<\/b> is automatically AJAX-enabled. This means that button click or other postback events triggered by controls in the template will be intercepted and converted into asynchronous AJAX calls to the server. <\/p>\n<p>Listing 1 demonstrates how to use an <b>UpdatePanel<\/b> control in a page in order to AJAX enable a <b>GridView,<\/b> which allows paging through customer data:<\/p>\n<pre>&lt;asp:UpdatePanel id=\"UpdatePanel1\"\" runat=\"server\"&gt;\n&#160;&#160; &lt;ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:GridView id=\"GridView1\"\" runat=\"server\" CellPadding=\"4\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataSourceID=\"SqlDataSource1\" ForeColor=\"#333333\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; GridLines=\"None\" AllowPaging=\"True\" AllowSorting=\"True\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AutoGenerateColumns=\"False\" DataKeyNames=\"CustomerID\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:BoundField DataField=\"CompanyName\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HeaderText=\"CompanyName\" SortExpression=\"CompanyName\" \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:BoundField DataField=\"ContactName\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HeaderText=\"ContactName\" SortExpression=\"ContactName\" \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:BoundField DataField=\"ContactTitle\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HeaderText=\"ContactTitle\" SortExpression=\"ContactTitle\" \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&lt;\/Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:GridView&gt;\n&#160;&#160;&#160; &lt;\/ContentTemplate&gt;\n&lt;\/asp:UpdatePanel&gt;\n<\/pre>\n<p class=\"caption\"><b>Listing 1<\/b>. Using the <b>UpdatePanel<\/b> control and <b>ContentTemplate<\/b>.<\/p>\n<p>As users page through customer records in the <b>GridView<\/b> control, or sort different columns, the <b>UpdatePanel<\/b> control automatically handles AJAX-enabling the call resulting in a partial-page update rather than a complete page refresh.<\/p>\n<h3>Displaying progress <\/h3>\n<p>Although the <b>UpdatePanel<\/b> is simple to use, you must take the end user into account when using it, especially if you don&#8217;t know how long an asynchronous postback may take to complete. Long requests may cause an end user to think that their request has failed or hung and they may start the request again, navigate to a different page or even close the browser. The solution is to provide them with a visual progress indicator so that they know that their request is being processed.<\/p>\n<p>The ASP.NET AJAX Framework includes the <b>UpdateProgress<\/b> control that can be used to provide users with a visual indication of whether or not their request is still being processed. Listing 2 shows an example of using the <b>UpdateProgress<\/b> control to display an animated image to an end user, while a Web Service is called that retrieves album information.<\/p>\n<pre>&lt;asp:UpdatePanel id=\"UpdatePanel1\"\" runat=\"server\"&gt;\n&#160;&#160;&#160; &lt;ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &amp;nbsp;Artist:&amp;nbsp;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:TextBox id=\"txtArtist\"\" runat=\"server\" \/&gt; \n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:Button id=\"btnSubmit\"\" runat=\"server\" Text=\"Get Albums\" \/&gt;\n\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:UpdateProgress id=\"upProgress\"\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DynamicLayout=\"false\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ProgressTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;img src=\"Images\/loading_animation_liferay.gif\" \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/ProgressTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:UpdateProgress&gt;\n\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:GridView id=\"GridView1\"\" runat=\"server\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;-- GridView contents omitted for brevity --\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:GridView&gt;\n&#160;&#160;&#160; &lt;\/ContentTemplate&gt;\n&lt;\/asp:UpdatePanel&gt;\n<\/pre>\n<p class=\"caption\"><b>Listing 2<\/b>. Using the UpdateProgress control.<\/p>\n<p>You&#8217;ll see that the <b>UpdateProgress<\/b> control has a <b>ProgressTemplate<\/b> that contains the content to show to the end user, while the <b>UpdatePanel<\/b> asynchronous postback is processed. Any content type of content (images, flash movies, videos, etc.) can be placed inside of the template. In cases where you&#8217;d like the content to take up a fixed amount of space on the page as opposed to dynamically being added, you can set the <b>DynamicLayout<\/b> property to false.<\/p>\n<p>The UpdateProgress control shown in Listing 2 is embedded directly within the target <b>UpdatePanel<\/b>. However, it can be embedded elsewhere in the page and linked to the appropriate <b>UpdatePanel<\/b> by setting its <b>AssociatedUpdatePanelID<\/b> property to the ID of the <b>UpdatePanel<\/b>. In cases where quick partial-page updates may occur, and you don&#8217;t want the <b>UpdateProgress<\/b> control to show its content, you can set the <b>DisplayAfter<\/b> property to the number of milliseconds that you&#8217;d like it to wait before displaying progress content. <b>DisplayAfter<\/b> defaults to a value of 500 milliseconds.<\/p>\n<p>Figure 1 demonstrates the end-user effect of using the <b>UpdateProgress<\/b> control. As the <b>UpdatePanel<\/b> is being refreshed with album information from a call to the Amazon.com Web Service, a progress indicator is displayed directly below the Artist textbox.<\/p>\n<p class=\"illustration\"><b><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/386-Figure1.gif\" alt=\"386-Figure1.gif\" \/><\/b><\/p>\n<p class=\"caption\"><b>Figure 1<\/b>. Using the UpdateProgress control to give visual feedback to end users as a call is made to the Amazon.com Web Service.<\/p>\n<h3>Nesting UpdatePanel controls<\/h3>\n<p>Multiple <b>UpdatePanel<\/b> controls can be added into a page in cases where different sections need to make AJAX calls to the server to avoid reloading the entire page. In addition to having multiple <b>UpdatePanel<\/b>s in a page, you can also nest <b>UpdatePanel<\/b>s to provide more granular AJAX functionality. For example, you may want to show a <b>GridView<\/b> control that displays information and allows a user to drill-down into additional details to achieve a master-details style view. Figure 2 shows an example of doing this using two <b>GridView<\/b> Controls.<\/p>\n<p class=\"illustration\"><b><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/386-Figure2.gif\" alt=\"386-Figure2.gif\" \/><\/b><\/p>\n<p class=\"caption\"><b>Figure 2<\/b>. Creating a master-details view of customer and order data.<\/p>\n<p>To accomplish this type of master-details view, an <b>UpdatePanel<\/b> is nested inside of a <b>GridView<\/b>&#8216;s <b>ItemTemplate<\/b>, as shown in Listing 3. As a user clicks the &#8220;View Orders&#8221; <b>LinkButton<\/b>, within each row shown in Figure 2, the <b>GridView<\/b> within the nested <b>UpdatePanel<\/b> is made visible. Any paging or sorting requests made within the nested <b>UpdatePanel<\/b> control will cause it to reload new data by making asynchronous AJAX requests, while data in the parent <b>GridView<\/b> control is left untouched.<\/p>\n<pre>&lt;asp:UpdatePanel id=\"up\"\" runat=\"server\" UpdateMode=\"Conditional\"&gt;\n&#160;&#160;&#160; &lt;ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:GridView id=\"GridView1\"\" runat=\"server\" CellPadding=\"4\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataSourceID=\"SqlDataSource1\" AllowPaging=\"True\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AllowSorting=\"True\" AutoGenerateColumns=\"False\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataKeyNames=\"CustomerID\" OnRowCommand=\"GridView1_RowCommand\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; -- Bound fields omitted for brevity --\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:TemplateField ItemStyle-Width=\"300px\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ItemTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:LinkButton id=\"lbOrders\"\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Text=\"View Orders\" CommandName=\"ViewOrders\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CommandArgument='&lt;%# Container.DataItemIndex %&gt;' \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:UpdatePanel id=\"up\"Child\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; UpdateMode=\"Conditional\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ContentTemplate&gt;\n&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;asp:GridView id=\"gvOrders\"\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AllowPaging=\"true\" PageSize=\"5\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Visible=\"false\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AllowSorting=\"True\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;AutoGenerateColumns=\"False\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; -- Bound fields omitted --\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:GridView&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:UpdatePanel&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:SqlDataSource id=\"sdsOrders\"\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ConnectionString=\"&lt;%$ ConnectionStrings:ConnStr %&gt;\"\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;SelectParameters&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:Parameter id=\"CustomerID\"\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DefaultValue=\"NULL\" \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/SelectParameters&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&lt;\/asp:SqlDataSource&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/ItemTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:TemplateField&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:GridView&gt;\n&#160;&#160;&#160; &lt;\/ContentTemplate&gt;\n&lt;\/asp:UpdatePanel&gt;\n<\/pre>\n<p class=\"caption\"><b>Listing 3<\/b>. Creating a master-details view of data using nested <b>UpdatePanel<\/b> control. <\/p>\n<p>The <b>UpdatePanel<\/b> control exposes an <b>UpdateMode<\/b> property that defaults to a value of &#8220;Always&#8221;. This means that any asynchronous request triggered anywhere within the page will cause the <b>UpdatePanel<\/b> to refresh itself. In cases where this behavior isn&#8217;t desired, the <b>UpdateMode<\/b> property can be assigned a value of &#8220;Conditional&#8221; so that only triggers associated with the control or child controls embedded within the control&#8217;s <b>ContentTemplate<\/b> can cause it to be refreshed through an asynchronous postback. Other controls outside of the <b>UpdatePanel<\/b> will not cause it to be refreshed. Additional information about <b>UpdatePanel<\/b> triggers is covered in the next section.<\/p>\n<p>The parent <b>UpdatePanel<\/b> control in Listing 3 has its <b>UpdateMode<\/b> set to Conditional so that any asynchronous postback operations caused by the nested <b>UpdatePanel<\/b> or by other controls in the page do not cause the parent <b>GridView<\/b> control to be refreshed. This minimizes the number of asynchronous postback requests made to the server.<\/p>\n<h3>Using triggers <\/h3>\n<p>While controls inside of an <b>UpdatePanel<\/b> control can cause it to perform asynchronous postbacks, other controls defined outside of the <b>UpdatePanel<\/b> can also act as &#8220;triggers&#8221; that cause the <b>UpdatePanel<\/b> to refresh itself with new data. Two types of triggers exist for <b>UpdatePanel<\/b>s including the <b>AsynchronousPostBackTrigger<\/b> control and <b>PostBackTrigger<\/b> control.<\/p>\n<p>An <b>AsynchronousPostBackTrigger<\/b> causes an <b>UpdatePanel<\/b>&#8216;s content to be updated asynchronously when a specific control&#8217;s event is fired such as a Button&#8217;s click event or a <b>DropDownList<\/b>&#8216;s <b>SelectedIndexChanged <\/b>event. A <b>PostBackTrigger<\/b> causes a regular postback operation to occur that reloads the entire page. When AJAX-enabling your Websites you&#8217;ll normally want to use the <b>AsynchronousPostBackTrigger<\/b> to stop postback operations from occurring.<\/p>\n<p>Listing 4 shows how to define a <b>DropDownList<\/b> control as a trigger that can perform a refresh of the <b>UpdatePanel<\/b>&#8216;s contents. This is done by using the <b>AsynchronousPostBackTrigger<\/b> control. Notice that the ID of the <b>DropDownList<\/b> control is defined using the <b>ControlID<\/b> property, and the event that causes the partial-page update of the <b>UpdatePanel<\/b> is defined using the <b>EventName<\/b> property. When the <b>SelectedIndexChanged<\/b> event fires, an asynchronous postback is made to the server and the <b>UpdatePanel<\/b>&#8216;s content is reloaded.<\/p>\n<pre>&lt;asp:UpdatePanel id=\"UpdatePanel1\"\" runat=\"server\"&gt;\n&#160;&#160;&#160; &lt;ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:GridView id=\"GridView1\"\" runat=\"server\" AllowPaging=\"True\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; AutoGenerateColumns=\"False\"\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataKeyNames=\"CustomerID\" DataSourceID=\"sdsCustomers\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; -- Column definitions omitted for brevity --\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/Columns&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:GridView&gt;\n&#160;&#160;&#160; &lt;\/ContentTemplate&gt;\n&#160;&#160;&#160; &lt;Triggers&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:AsyncPostBackTrigger ControlID=\"DropDownList1\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventName=\"SelectedIndexChanged\" \/&gt;\n&#160;&#160;&#160; &lt;\/Triggers&gt;\n&lt;\/asp:UpdatePanel&gt;\n<\/pre>\n<p class=\"caption\"><b>Listing 4<\/b>. Defining triggers to perform partial-page updates on the contents of an <b>UpdatePanel<\/b>.<\/p>\n<p>In cases where you&#8217;d like to prevent controls defined within an <b>UpdatePanel<\/b>&#8216;s <b>ContentTemplate<\/b> from triggering an asynchronous postback operation, you can set the <b>UpdatePanel<\/b>&#8216;s <b>ChildrenAsTriggers <\/b>property to <b>false<\/b> and the <b>UpdateMode<\/b> to &#8220;Conditional&#8221;. Any events raised by child controls in the <b>ContentTemplate<\/b> of the control will be ignored, while events raised by triggers such as the one shown in Listing 4 will cause a partial-page update to occur, if needed.<\/p>\n<p>Listing 5 shows an example of setting the <b>ChildrenAsTriggers<\/b> property to false to prevent LinkButtons clicked within a <b>DataList<\/b> control from updating the contents of an <b>UpdatePanel<\/b>. While the LinkButtons don&#8217;t cause the <b>UpdatePanel<\/b> to refresh itself, they do cause another <b>UpdatePanel<\/b> defined in the page to be refreshed so that additional details about employees can be shown to the end user (see Figure 3).<\/p>\n<pre>&lt;div style=\"width: 400px\"&gt;\n&#160;&#160;&#160; &lt;div style=\"float: left; width: 200px;\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; Territories:&lt;br \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:UpdatePanel id=\"up\"Territories\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ChildrenAsTriggers=\"false\" UpdateMode=\"conditional\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:DataList id=\"dlTerritories\"\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CellPadding=\"4\" DataKeyField=\"TerritoryID\"\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataSourceid=\"sdsTerritories\"\" ForeColor=\"#333333\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; OnItemCommand=\"DataList1_ItemCommand\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ItemTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:LinkButton runat=\"server\" id=\"lbTerritories\"\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Text='&lt;%# Eval(\"TerritoryDescription\") %&gt;'\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CommandName=\"TerritoryClick\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CommandArgument='&lt;%#Eval(\"TerritoryID\") %&gt;' \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Style=\"text-decoration: none;\" \/&gt;&lt;br \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/ItemTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:DataList&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:UpdatePanel&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:SqlDataSource id=\"sdsTerritories\"\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ConnectionString=\"&lt;%$ ConnectionStrings:ConnStr %&gt;\"\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SelectCommand=\"SELECT TOP 20 [TerritoryID], [TerritoryDescription] \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; FROM [Territories] ORDER BY [TerritoryDescription]\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:SqlDataSource&gt;\n&#160;&#160;&#160; &lt;\/div&gt;\n&#160;&#160;&#160; &lt;div style=\"float: right; width: 200px\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; Employees:&lt;br \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:UpdatePanel id=\"up\"Employees\" runat=\"Server\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:DataList id=\"dlEmployees\"\" runat=\"server\" CellPadding=\"4\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataSourceid=\"sdsEmployees\"\" ForeColor=\"#333333\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;ItemTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:Label id=\"NameLabel\"\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Text='&lt;%# Eval(\"Name\") %&gt;'&gt;&lt;\/asp:Label&gt;&lt;br \/&gt;&lt;br \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/ItemTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:DataList&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/ContentTemplate&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:UpdatePanel&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:SqlDataSource id=\"sdsEmployees\"\" runat=\"server\" \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ConnectionString=\"&lt;%$ ConnectionStrings:ConnStr %&gt;\"\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SelectCommand=\"SELECT Employees.FirstName + ' ' + \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Employees.LastName AS Name FROM Employees INNER JOIN \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EmployeeTerritories ON Employees.EmployeeID = \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EmployeeTerritories.EmployeeID WHERE \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (EmployeeTerritories.TerritoryID = @TerritoryID)\"&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;SelectParameters&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;asp:Parameter id=\"TerritoryID\"\" \/&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/SelectParameters&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;\/asp:SqlDataSource&gt;\n&#160;&#160;&#160; &lt;\/div&gt;\n&lt;\/div&gt;\n<\/pre>\n<p class=\"caption\"><b>Listing 5<\/b>. Using the ChildrenAsTriggers property to stop child control&#8217;s of an <b>UpdatePanel<\/b> from triggering an asynchronous postback operation. <\/p>\n<p>The results of this are displayed in Figure 3. When a territory is clicked, employees in that territory will be shown.<\/p>\n<p class=\"illustration\"><b><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/386-Figure3.gif\" alt=\"386-Figure3.gif\" \/><\/b><\/p>\n<p class=\"caption\"><b>Figure 3<\/b>. <b>LinkButtons<\/b> defined in an <b>UpdatePanel<\/b> trigger a separate <b>UpdatePanel<\/b> to display additional details about employees.<\/p>\n<p>The <b>UpdatePanel<\/b> where the controls are defined is not updated since the <b>ChildrenAsTriggers<\/b> property is set to false.<\/p>\n<h3>Handling UpdatePanel events on the client <\/h3>\n<p>The <b>UpdatePanel<\/b> control handles all asynchronous requests to the server, so you don&#8217;t have to worry about writing JavaScript code. This is great from a productivity and maintenance standpoint but there will be times when you want to know when an <b>UpdatePanel<\/b> request is going to start, or when data has returned and is about to be updated in the page. For example, you may want to access data returned by an <b>UpdatePanel<\/b> and use it to make another asynchronous postback request. Or, you may want to animate the <b>UpdatePanel<\/b> as a request is started so that the end user sees what is happening and knows when content in a particular area of a page has been refreshed. All of this can be done by using a JavaScript class provided by the ASP.NET AJAX script library, called the <b>PageRequestManager<\/b>.<\/p>\n<p>The <b>PageRequestManager<\/b> lives in the <b>Sys.WebForms<\/b> namespace in the ASP.NET AJAX script library and allows you to tie into requests and responses processed by one or more <b>UpdatePanel<\/b>s in a page. It&#8217;s responsible for managing partial-page updates that occur within a page as well as managing the client page life-cycle. By using it you can tie into several different events and act upon them. <b>PageRequestManager<\/b> also exposes properties and methods that can be used to check if asynchronous requests are in process. It can also be used to abort existing requests and even cancel pending requests.<\/p>\n<p>Events exposed by the <b>PageRequestManager<\/b> class include <b>initializeRequest<\/b>, <b>beginRequest<\/b>, <b>pageLoading<\/b>, <b>pageLoaded<\/b> and <b>endRequest<\/b>. The following table provides more details about these events and when they are fired. <\/p>\n<\/p>\n<table>\n<tbody>\n<tr>\n<td valign=\"top\">\n<p><b>Event<\/b><\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>Description<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>initializeRequest<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Raised when an asynchronous postback is first initialized. This event can be used to cancel requests in cases where another request is already in process.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>beginRequest<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Raised when an asynchronous postback begins. This event can be used to animate an <b>UpdatePanel<\/b> container within a page to provide users with a visual cue that an asynchronous postback request is starting.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>pageLoading<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Raised after data is received from an asynchronous postback request but before the data is updated in the page. This event can be used in cases where you&#8217;d like to change data returned from the server using JavaScript or provide an effect on the <b>UpdatePanel<\/b> to signify that content is about to be updated.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>pageLoaded<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Raised when data in a page is updated after a synchronous or asynchronous request.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>endRequest<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Raised after an asynchronous postback request is completed. Any errors that occurred during the request can be processed here.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>To access the <b>PageRequestManager<\/b> you can call its <b>getInstance()<\/b> method on the client-side as shown next:<\/p>\n<pre>var prm = Sys.WebForms.PageRequestManager.getInstance();\n<\/pre>\n<p>Once the <b>PageRequestManager<\/b> object is available, you can define event handlers for the different events that it exposes and attach to them. Listing 6 shows how to attach an event handler to the <b>endRequest<\/b> event and access data returned from the asynchronous postback request.<\/p>\n<pre>Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequest);\n\n\n\n\nfunction EndRequest(sender, eventArgs)\n{\n&#160;&#160;&#160; if (eventArgs.get_error() != undefined &amp;&amp; \n&#160;&#160;&#160;&#160;&#160;&#160;&#160; eventArgs.get_error().httpStatusCode == '500')\n&#160;&#160;&#160; {\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; var errorMessage = eventArgs.get_error().message;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; eventArgs.set_errorHandled(true);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160; alert(errorMessage);\n&#160;&#160;&#160; }\n&#160;&#160;&#160; else\n&#160;&#160; &#160;{\n&#160;&#160;&#160;&#160;&#160;&#160; &#160;GetMap($get(\"hidField\").value); \n&#160;&#160; &#160;}\n}\n<\/pre>\n<p class=\"caption\"><b>Listing 6<\/b>. This code shows how to attach an event handler to the <b>endRequest<\/b> event of the <b>PageRequestManager<\/b>.<\/p>\n<p>Once a request is completed, errors are checked and if none are found, data returned by the request is accessed and passed to another method for processing.<\/p>\n<p>Notice that the parameter signature for the <b>EndRequest()<\/b> event handler mirrors the one found in the .NET framework where the sender of the event as well as any event arguments are passed as parameters. The <b>eventArgs<\/b> parameter can be used to check if any errors occurred during the request by calling the error property which can be used to access the HTTP status code of the request. If a 500 error is found then the code accesses the error message by calling the message property, marks that the error has been handled and shows the error message to the end user. If no error occurs, a hidden field, named <b>hidField<\/b>, which is returned from the asynchronous postback, is accessed to get a value needed by a <b>GetMap()<\/b> method, which is used to display a Virtual Earth map.<\/p>\n<p>The <b>PageRequestManager<\/b> can also be used to abort or cancel asynchronous postback requests by handling the <b>initRequest<\/b> event. Listing 7 shows an example of canceling a request in cases where an <b>UpdatePanel<\/b> is in the process of making a request and the end user is impatiently clicking a Refresh button.<\/p>\n<pre>Sys.Application.add_init(Init);\nvar prm = null;<\/pre>\n<p><\/p>\n<pre>function Init(sender)\n{\n&#160;&#160;&#160;&#160;&#160; prm = Sys.WebForms.PageRequestManager.getInstance();\n&#160;&#160;&#160;&#160;&#160; \/\/Ensure EnablePartialRendering isn't false which will prevent\n&#160;&#160;&#160;&#160;&#160; \/\/accessing an instance of the PageRequestManager\n&#160;&#160;&#160;&#160;&#160; if (prm)\n&#160;&#160;&#160;&#160;&#160; {\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (!prm.get_isInAsyncPostBack())\n&#160;&#160;&#160;&#160;&#160; &#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; prm.add_initializeRequest(InitRequest);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }\n&#160;&#160;&#160;&#160;&#160; }\n}<\/pre>\n<p><\/p>\n<pre>function InitRequest(sender,args)\n{\n&#160;&#160;&#160;&#160;&#160; if (prm.get_isInAsyncPostBack() &amp; args.get_postBackElement().id == \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 'btnRefresh') {\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/Could abort current request by using:&#160; prm.abortPostBack();&#160;&#160; \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/Cancel most recent request so that previous request will complete \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \/\/and display\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; args.set_cancel(true);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; alert(\"A request is currently being processed.&#160; Please \" + \n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; \"wait before refreshing again.\");\n&#160;&#160;&#160;&#160;&#160; }\n}<\/pre>\n<p class=\"caption\"><b>Listing 7<\/b>. This code shows how the <b>PageRequestManager<\/b>&#8216;s initRequest event can be used to cancel a pending asynchronous postback request.<\/p>\n<p>The code in Listing 7 starts by accessing an instance of the <b>PageRequestManager<\/b> in the Application&#8217;s <b>init<\/b> phase and ensuring that an asynchronous postback isn&#8217;t already in progress on the page. If no asynchronous postback is occurring, the <b>InitRequest<\/b> event handler is attached to the <b>initializeRequest<\/b> event. Once the <b>InitRequest<\/b> handle is called, a call is made to the <b>PageRequestManager<\/b>&#8216;s <b>isInAsyncPostBack<\/b> property and the event argument&#8217;s <b>postBackElement<\/b> property (the event argument is of type <b>InitializeRequestEventArgs<\/b>). The <b>isInAsyncPostBack<\/b> property returns a Boolean value indicating if an asynchronous postback is currently in progress and <b>postBackElement<\/b> property provides access to the control that triggered the request.<\/p>\n<p>If an asynchronous postback is already in progress and a new request is triggered by a button with an ID of <b>btnRefresh<\/b>, the pending request is cancelled by assigning a value of true to <b>set_cancel<\/b>. A message is then displayed to the end user letting them know that a request is already being processed and that they need to wait. The <b>PageRequestManager<\/b> class can be used to perform several other actions such as animating an <b>UpdatePanel<\/b> before a request is made and after the response is processed.<\/p>\n<h2>Conclusion <\/h2>\n<p>The ASP.NET AJAX Framework provides a simple and productive way to add AJAX functionality into new or existing Websites. With a minimal amount of effort you can make your applications perform more efficiently and provide end users with a richer experience than traditional Web applications by using partial-page updates. <\/p>\n<p>In this article you&#8217;ve seen how the ScriptManager and <b>UpdatePanel<\/b> controls can be used to make asynchronous postbacks from the browser to the server and how different types of triggers can initiate the requests. You&#8217;ve also seen how <b>UpdatePanel<\/b> controls can be nested to provide a master-details style view of data and how the <b>UpdateMode<\/b> and <b>ChildrenAsTriggers<\/b> properties can control how and when an <b>UpdatePanel<\/b>&#8216;s content is updated. Finally, you&#8217;ve seen how the <b>PageRequestManager<\/b> client-side class can be used to notify you of partial-page update requests and responses. <\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Microsoft&#8217;s ASP.NET AJAX Extensions provide developers with a quick and simple way to add AJAX functionality into any ASP.NET Website. In this article, Dan Wahlin demonstrates how to use the UpdatePanel control, which performs asynchronous postback operations that update a portion of a page rather than the entire page itself. &hellip;<\/p>\n","protected":false},"author":221823,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4291,4156,4157,4766,4179,4764,4765],"coauthors":[],"class_list":["post-258","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-ajax","tag-asp","tag-asp-net","tag-scriptmanager","tag-source-control","tag-updatepanel","tag-xmlhttp"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221823"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=258"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/258\/revisions"}],"predecessor-version":[{"id":91080,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/258\/revisions\/91080"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=258"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}