AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1285&pId=-1
Tip and Tricks: ASP.NET 2.0 AJAX 1.0 Extensions and Master Pages
page
by Bilal Haidar
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 74053/ 80

Introduction

In my last article, I went into details on how to integrate ASP.NET 2.0 AJAX 1.0 UpdatePanels with UserControls in your ASP.NET 2.0 web application.

I have also promised to deliver another article that discusses using ASP.NET 2.0 AJAX 1.0 UpdatePanels with Master Pages.

There are some tips and tricks regarding using AJAX when you have Master Pages in your website. In this article, we are going to illustrate to you several ways you can use the UpdatePanel together with Master Pages, whether to include ScriptManagers inside the Master Page or directly inside the Content Pages. In addition, we will discuss how you will be able to add any additional Script References or Service References into the ScriptManager placed inside a Master Page from within the Content Page by using the ScriptManagerProxy. The ScriptManagerProxy allows UserControls and Content Pages to add script and service references when the ScriptManager is placed in a parent element.

We will start by developing a simple ASP.NET web application in which we have a Master Page together with a Content Page, and then we will explore the different options we have to enable the web application with AJAX.

Requirements

Before you start reading on with this article make sure you have the following applications and add-ons installed on your machine:

·         Visual Studio Professional 2005

·         Microsoft SQL Server Standard Edition

·         Microsoft ASP.NET 2.0 AJAX Extensions 1.0

·         Internet Information Services 5.0, 6.0, 7.0

The above were used to develop the sample downloadable application. However, you can also use the Visual Web Developer 2005 Express and Microsoft SQL Server 2005 Express Editions to run the example that we will be developing in this article. To download them you can visit the following URLs:

Visual Web Developer 2005 Express Edition

Microsoft SQL Server 2005 Express Edition

Microsoft ASP.NET 2.0 AJAX Extensions 1.0

Life without AJAX

To start with we will create a new ASP.NET AJAX-Enabled Web Site by selecting a template that has been added to your Visual Studio Templates upon the installation of the Microsoft ASP.NET 2.0 AJAX 1.0 Extensions. You can refer back to Figure 1 below to see how to select the right template:

Figure 1: Selecting ASP.NET AJAX-Enabled Web Site template

The reason behind creating a new website based on the above template is that the ASP.NET Web Application’s configuration file will have all the sections required to run AJAX successfully.  This way you will save some time.

In this first version of the application, we will develop a Master Page and a Content Page:

MainMaster.master

MainContent.aspx

Before discussing the functionality of the above content page, you will need to have on whatever version of Microsoft SQL Server that you are using the Northwind database that was part of the Microsoft SQL Server 2000. If you do not already have it, you can visit this URL and download it from there:

Northwind and pubs Sample Databases for SQL Server 2000

The MainMaster.master will show a simple layout for the web application we are working with and the MainConten.aspx page will simply show a web form that is used to filter a GridView that is bound to the Employees data table inside the Northwind database.

The Master Page will have a simple layout including a header, footer, and content sections. The layout is shown in Figure 2 below:

Figure 2: Master Page layout

The MainContent page will include a simple TextBox together with a Button that are used to filter a shown GridView that is bound to the Employees data table inside the Northwind database. The MainContent.aspx page is shown in Figure 3 below:

Figure 3: Content Page showing a filtered GridView

Once you type in some letter from the FirtstName field and press the Button, then the GridView will be filtered accordingly.

That was straight forward and nothing new in here!  Let us now start adding some AJAX!!

ScriptManager in Master Page

In this first scenario we will place the ScriptManager inside the Master Page and add an UpdatePanel on the Content Page to have an AJAX-style processing. The Master Page markup is as follows:

Listing 1

<%@ Master Language="C#"
 AutoEventWireup="true" CodeFile="MainMaster.master.cs"
 Inherits="MainMaster" %>
<!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>Untitled Page</title>
</html>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <div id="container">
        <div id="header">
            Header goes Here
        </div>
        <div>
            <div id="content">
                <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
                    
                </asp:contentplaceholder>
            </div>
            <div id="footer">
                Footer goes Here
            </div>
        </div>
    </div>
    </form>
</body>

As you can see, we have placed the ScriptManager inside the Master Page. Let us now add an UpdatePanel into the Content page. The code of the ContentPage.aspx is shown below as follows:

Listing 2

<%@ Page Language="C#"
 MasterPageFile="~/MainMaster.master" AutoEventWireup="true"
 CodeFile="MainContent.aspx.cs" StylesheetTheme="Default"
 Inherits="MainContent" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
    <asp:Label ID="lblFilterText"
 AssociatedControlID="txtFilterText" runat="server"
 Text="Filter the GridView: " />&nbsp;&nbsp;
    <asp:TextBox ID="txtFilterText" runat="server" />
    <br />
    <asp:Button ID="btnFilter"
 runat="server" Text="Filter The GridView" />
        <br />
        <br />
        <asp:GridView ID="GridView1"
 runat="server" AutoGenerateColumns="False" CellPadding="4"
            DataKeyNames="EmployeeID"
 DataSourceID="SqlDataSource1" ForeColor="#333333"
 GridLines="None">
            <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <Columns>
                <asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" InsertVisible="False"
                    ReadOnly="True" SortExpression="EmployeeID" />
                <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
                <asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
                <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
                <asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" />
            </Columns>
            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
            <EditRowStyle BackColor="#999999" />
            <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
            <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
            <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
        </asp:GridView>
        <asp:SqlDataSource
 ID="SqlDataSource1" runat="server"
 ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT
 [EmployeeID], [LastName], [FirstName], [Title], [City], [Country] FROM
 [Employees] WHERE ([FirstName] LIKE '%' + @FirstName + '%')">
            <SelectParameters>
                <asp:ControlParameter ControlID="txtFilterText" DefaultValue="%" Name="FirstName"
                    PropertyName="Text" Type="String" />
            </SelectParameters>
        </asp:SqlDataSource>
    </ContentTemplate>
</asp:UpdatePanel>
</asp:Content>

Running the above ContentPage.aspx can be shown in Figure 4 below:

Figure 4: Running ContentPage.aspx with UpdatePanel added

In this scenario we have seen how to enable the application with AJAX by placing the UpdatePanel inside the Content Page while keeping the ScriptManager in the Master Page.

ScriptManager outside, Script and Service references inside

Looking back at the above section, you notice that if any content page in your web application, wants to add a reference to a JavaScript file, this file should be added a script reference at the ScriptManager location. Therefore, we conclude that, the ScriptManager located inside the MasterPage should include all references to JavaScript files inside your web application. However, this is not a neat solution to have the MasterPage hold all references to scripts and services consumed by the content pages.

ScriptManagerProxy is your salvation!

The AJAX team was aware of the above problem and that’s why in my own guessing they have included this server-side class. The ScriptManagerProxy is used to add script and service references to content pages or user controls when the ScriptManager is placed either in the Master Page or Parent page respectively!

Hence, in this scenario, we will call the beginRequest function, that is part of the PageRequestManager that has several functions that are called during the life-cycle of an asynchronous request, to show an alert box informing the user that the request has started. The JavaScript code written will be placed inside a JavaScript file and embedded to the page as a reference using the ScriptManagerProxy as follows:

Listing 3

<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<Scripts>
<asp:ScriptReference Path="myFunctions.js" />
</Scripts>
</asp:ScriptManagerProxy>
<script type="text/javascript"
 language="javascript">   Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
</script>

As you can see we have added a reference to the myFunctions.js file and attached a handler to the beginRequest function of the PageRequestManager Class.

The PageRequestManager has several methods that are worth mentioning in here:

initializeRequest: This function is raised automatically before the request is initialized for an asynchronous request. This function takes as one of the input parameters the InitializeRequestEventArgs object. This object provides the element that caused the asynchronous postback and the request object. This function can be used to cancel an asynchronous postback.

beginRequest: This function is raised just before the request is sent to the server. This function takes as one of the input parameters the BeginRequestEventArgs object. This object provides the element that caused the asynchronous postback and the request object. This function can be used to show/hide an UpdateProgress control.

pageLoading: This function is raised just after the response is back from the server and before any content is updated on the page. This function takes as one of the input parameters the PageLoadingEventArgs object. This object provides information about the panels that are to be deleted and update as a result of the latest asynchronous postback request.

pageLoaded: This function is raised just after the panels have been updated on the page as a result of the latest asynchronous postback request. This function takes as one of the input parameters the PageLoadedEventArgs object. This object provides information about the panels that were created or updated as a result of the latest asynchronous postback request. This function is also raised for synchronous requests too and in that case, the PageLoadedEventArgs contains information only about the panels that were created.

endRequest: This function is raised when the asynchronous request has finished. This function takes as one of the input parameters the EndRequestEventArgs object. This object provides information about any errors if any that occurred while processing the asynchronous postback request. It also makes available the response object.

The myFunctions.js file includes the following functions:

Listing 4

function BeginRequestHandler(sender, args)
{
  // Get the postback element that is part of the args
  // parameter which is of type BeginRequestEventArgs class
  var elem = args.get_postBackElement();
         
  // Show the alert box
  alert(elem.value + ' is processing...');
}

Inside the beginRequest handler, the code gets the control that caused the asynchronous postback by using the BeginRequestEventArgs client class’s function, get_postBackElement. Finally, an alert box is shown to inform the user about the control that started an asynchronous postback.

To get more information about the PageRequestManager class we recommend you check the AJAX documentation page located at http://ajax.asp.net/docs. This class has other functions that are useful throughout the AJAX page-life cycle! To get more information about the AJAX life cycle, make sure to check those two blog posts at:

Microsoft ASP.NET AJAX - Request Life Cycle

More on AJAX Client Side Life Cycle

As a conclusion of this scenario, you can see how easily it is to add both scripts and service references from inside the content page. This way, each page will be adding its own related scripts or services and not having the ScriptManager located in the Master Page hold all the script or services references for all content pages inside the web application.

ScriptManager inside each Content Page

In this scenario we shall discuss the last option we have to make use of AJAX and Master Pages.

In the above two options, we discussed embedding the ScriptManager inside the Master Pages itself. Once any of the Content Pages uses an UpdatePanel in its HTML markup, asynchronous requests will work like charm. In the second scenario we showed how to embed specific JavaScript file to the content page despite the fact the ScriptManager is placed within the Master Page. We used for this purpose the ScriptManagerProxy.

In this scenario, we will demonstrate how to enable AJAX in a web application that uses a Master Page by placing the ScriptManager on the content page itself.

The content page now looks as this:

Listing 5

<%@ Page Language="C#"
 StylesheetTheme="default"
 MasterPageFile="~/MainMasterWithoutManager.master"
 AutoEventWireup="true" CodeFile="MainContent1.aspx.cs"
 Inherits="MainContent1" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
    <asp:ScriptReference Path="~/myFunctions.js" />
</Scripts>
</asp:ScriptManager>
 
<script type="text/javascript" language="javascript">
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequestHandler);
</script>
 
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
    <asp:Label ID="lblFilterText"
 AssociatedControlID="txtFilterText" runat="server"
 Text="Filter the GridView: " />&nbsp;&nbsp;
    <asp:TextBox ID="txtFilterText" runat="server" />
    <br />
    <asp:Button ID="btnFilter" runat="server" Text="Filter The GridView" />
        <br />
        <br />
        <asp:GridView ID="GridView1"
 runat="server" AutoGenerateColumns="False"
 CellPadding="4"
            DataKeyNames="EmployeeID"
 DataSourceID="SqlDataSource1" ForeColor="#333333"
 GridLines="None">
            <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <Columns>
                <asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID"
 InsertVisible="False"
                    ReadOnly="True" SortExpression="EmployeeID" />
                <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
                <asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
                <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
                <asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" />
            </Columns>
            <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
            <EditRowStyle BackColor="#999999" />
            <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
            <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
            <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
            <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
            <EmptyDataTemplate>
                <strong>No data mactches your filter!!</strong>
            </EmptyDataTemplate>
        </asp:GridView>
        <asp:SqlDataSource
 ID="SqlDataSource1" runat="server"
 ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT
 [EmployeeID], [LastName], [FirstName], [Title], [City], [Country] FROM
 [Employees] WHERE ([FirstName] LIKE '%' + @FirstName + '%')"
 OnSelecting="SqlDataSource1_Selecting">
            <SelectParameters>
                <asp:ControlParameter ControlID="txtFilterText" DefaultValue="%" Name="FirstName"
                    PropertyName="Text" Type="String" />
            </SelectParameters>
        </asp:SqlDataSource>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server">
            <ProgressTemplate>
                <p>
                    <img src="loading.gif" alt="" />&nbsp; <strong>Your
 request is processed!!</strong></p>
            </ProgressTemplate>
        </asp:UpdateProgress>
    </ContentTemplate>
</asp:UpdatePanel>
</asp:Content>

The behavior in this page is the same as that in the above scenarios mentioned above with the only difference is that the ScriptManager is placed within the content page. Based on this scenario each content page that wants to be AJAX enabled has to add its own instance of the ScriptManager leaving the Master Page unaware of ScriptManager.

What to choose?

We have seen several scenarios throughout this article that discuss how to handle Master Pages and Content Pages when AJAX is to be added to a website. One would ask which scenario is best to follow. Well the normal answer would be it depends on the situation you are experiencing. However, we don’t like normal answers and we would be strict in saying that, it is recommended to place the ScriptManager inside the Master Page. This way, the every page will be AJAX enabled and what is rest is simply add an UpdatePanel to the content page itself and that’s it!

Another advantage of using this scenario is the presence of ScriptManagerProxy which makes it logical and optimized to place inside each content page the relevant scripts and services’ references. This way, the Master Page will not be responsible to include all the scripts and services required by all the content pages in the website. Each page will include only the needed and required scripts and services.

Downloads
References

To start learning with Microsoft ASP.NET 2.0 AJAX Extensions 1.0 we would strongly recommend starting by reading the AJAX documentation. This should be your first reference to start with. In addition, you can visit the official website of ASP.NET and download all of the videos there created by Joe Stagner on the AJAX and AJAX Toolkit. Finally, there are several MSDN web casts that are worth watching. Rob Bagby, Microsoft Developer Evangelist, has started a series of web casts on the Client Script side of AJAX. There are currently two downloadable web casts to watch and next week he will be presenting the rest. To find out more, please check out Rob Bagby's blog.

Conclusion

In this article, we have shown you how to deal with Master Page and Content Pages when AJAX is to be added to an existing ASP.NET Web application or even when creating new applications. Different scenarios were discussed including placing the ScriptManager inside the Master Page, include ScriptManager inside Master Page and put the ScriptManagerProxy inside each content page if that content page wants to reference a JavaScript file or an AJAX Service, and placing the ScriptManager inside each content page in the web application. In addition we have placed a section that shows the pros and cons of each scenario and which scenario to follow.

Happy Ajaxified Dot Netting!!



©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-25 5:58:55 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search