Home
    Shop
    Advertise
    Write For Us
    Affiliate
    Newsletter
    Contact

Master Pages in ASP.Net 2.0 - An Advanced Look

Introduction

One of the new features of ASP.Net 2.0 is Master Pages. Master Pages enables us to apply the same page layout to multiple pages in a Web Application. A page that uses a master page is known as the content page.

 

Using Master Pages we can create a consistent look and feel for our websites. Pages in a web application have the standard elements such as logos, menus, copyright notices, etc. that are repeated on each and every page. And usually a web-site has a single layout design that each page corresponds to. Using master pages, we can place all these elements and define the layout and design in a master page. And when we base a content page on this master page, then all of the content pages will automatically include all of the standard elements and will define whatever layout you defined in the master page.

In this article, I'll spin through a small sample application to help you in understanding the advantages of master pages and how can work with them. I'll also explore some of the advanced features of Master Pages, such as modifying header element from the content page, so that if each content page needs to display a different Title Header, you can easily have it done. I will also take a look at loading the master page at run-time, and use of Nested Master pages.

Prerequisites

This tutorial assumes that you own a copy of Visual Studio 2005 or Visual Web Developer Express. It also assumes that you are familiar with ASP.Net 2.0 basics.

Creating the Website

If you have an existing web site, you can skip this section. Otherwise, you can create a new web site and page by following these steps.

To create a file system Web site:

- Open Visual Studio 2005.

- On the File menu, open New and click on Web Site.

The New Web Site dialog box appears.

- Under Visual Studio installed templates, click ASP.NET Web Site.

- In the Location box, enter the name of the folder where you want to keep the pages of your Web site.

For example, type the folder name C:\WebSites\mySite.

- In the Language list, click Visual Basic (or the language you prefer to work with).

- Click OK.

Visual Web Developer creates the folder and a new page named Default.aspx.

Creating a Simple Master Page

Right-click in the solution explorer and select Add New Item. Select Master Page from the template and provide a name for the page. In this example I am using myMaster.master (where .master is the extension of the file). Click Add.

This will add the .master file to the project. Which is our master page.

A Master Page can contain the same Web controls, User controls, HTML content, and scripts that can be added to a standard ASP.NET page. There are three important differences between a Master Page and a normal ASP.NET page.

First, unlike a normal ASP.NET page, the name of a Master Page must end with the special extension .master. This extension marks the page as a Master Page. Furthermore, an ASP.NET application is configured so that you cannot request pages with the .master extension.

Second, a Master Page includes a <%@ Master %> directive instead of the normal <%@ Page %> directive. The <%@ Master %> directive supports many of the same attributes as the <%@ Page %> directive. For example, you can specify the programming language of the page with the directive <%@ Master Language="vb" %>.

The final difference between a Master Page and a normal ASP.NET page is that a Master Page can contain zero or more ContentPlaceHolder controls. A ContentPlaceHolder control can be used only within a Master Page. This control marks an area of a Master Page that can be overridden by a particular content page.

Design myMaster.master to meet the following:

The HTML code for this is:

<body>

    <form id="form1" runat="server">

    <div>

        <table border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%">

            <tr>

                <td colspan="2" style="height: 50px; background-color: royalblue" align="left" valign="top">

                    <asp:Label ID="Label1" runat="server" Font-Names="Verdana" Font-Size="X-Large" Font-Underline="True"

                        ForeColor="WhiteSmoke" Text="Welcome to the Master/Content Tutorial"></asp:Label><br />

                    <asp:Label ID="Label2" runat="server" Font-Names="Verdana" ForeColor="WhiteSmoke"

                        Text="Writer: M.Salman Khalid."></asp:Label></td>

            </tr>

            <tr>

                <td style="width: 75px; background-color: royalblue">

                </td>

                <td>

                    <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">

                    </asp:contentplaceholder>

                </td>

            </tr>

            <tr>

                <td colspan="2" style="height: 50px; background-color: royalblue" align="center">

                    &nbsp;<asp:LinkButton ID="LinkButton2" runat="server" ForeColor="WhiteSmoke">Microsoft</asp:LinkButton>

                    <asp:Label ID="Label3" runat="server" ForeColor="WhiteSmoke" Text="*" Width="3px"></asp:Label>

                    <asp:LinkButton ID="LinkButton3" runat="server" ForeColor="WhiteSmoke">MSDN</asp:LinkButton>

                    <asp:Label ID="Label4" runat="server" ForeColor="WhiteSmoke" Text="*" Width="3px"></asp:Label>

                    <asp:LinkButton ID="LinkButton4" runat="server" ForeColor="WhiteSmoke">Channel 9</asp:LinkButton>

                    <asp:Label ID="Label5" runat="server" ForeColor="WhiteSmoke" Text="*" Width="3px"></asp:Label>

                    <asp:LinkButton ID="LinkButton1" runat="server" ForeColor="WhiteSmoke">Code Project</asp:LinkButton></td>

            </tr>

        </table>

        &nbsp;

    </div>

    </form>

</body>

In the above HTML code, the ContentPlaceHolder control is what identifies the area where the content place data will come. With Master/Content pages, you can have multiple ContentPlaceHolder controls in the Master Page.

Creating a Content Page

Right-click the project in the solution explorer and select Add New Item. Select Web Page from the template and check Select Master Page. Click on Add. This will open the Select Master Page dialog box, listing all the master pages defined in the project. Select the master page myMaster.master and click OK.

The HTML code for the new content page is:

<%@ Page Language="VB" MasterPageFile="~/myMaster.master" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" title="Untitled Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

</asp:Content>

This is how the Content Page looks when switched to design-view:

The area around the ContentPlaceHolder is disabled. The area defined by the content place holder acts as a normal web-page. You can drag-n-drop controls here like any other ASP.Net page.

One draw-back of using the master/content pages is that for the content pages, you can't use a code-behind class.

Nested Master Pages

We've looked at how one can create a single Master Page and base a content page on the Master Page.

Furthermore, if you have the need, you can even nest multiple Master Pages. For example, you can create one Master Page for the entire Web site and then nest Master Pages below the site Master Page for individual sections.

Visual Studio/Visual Web Developer does not provide designer support for doing this. So, if you want to nest Master Pages, you'll need to stick to either source code view or build your pages using Notepad.

For example, following could be used for a Site Master Page. This Master Page contains the opening and closing HTML and Form tags and a single ContentPlaceHolder control.

<%@ Master %>

<html>

<head>

    <title>Site Master</title>

</head>

<body bgcolor="LightGreen">

    <form id="form1" runat="server">

        <h1>Site Master Page</h1>

        <asp:contentplaceholder

            id="SiteContentPlaceHolder"

            runat="server" />

    </form>

</body>

</html>

And the following could be the nested master page. This Master Page overrides the content in the Site Master Page. Notice that the <%@ Master %> directive refers to the SiteMaster.master Master Page.

<%@ Master  MasterPageFile="~/SiteMaster.master" %>

<asp:content ID="Content1"

    ContentPlaceHolderID="SiteContentPlaceHolder"

    runat="server">

    <table width="100%" bgcolor="LightYellow">

    <tr>

        <td colspan="2">

        <h1>Section Master Page</h1>

        </td>

    </tr>

    <tr>

        <td>

        <asp:ContentPlaceHolder  

            id="LeftColumn"

            Runat="Server" />            

        </td>

        <td>

        <asp:ContentPlaceHolder  

            id="RightColumn"

            Runat="Server" />    

        </td>

    </tr>

    </table>

</asp:content>

Finally, the content is based on the Section Master Page. Notice that this page overrides the two ContentPlaceHolder controls contained in the Section Master Page.

<%@ Page MasterPageFile="~/SectionMaster.master" %>

<asp:Content ID="Content1"   

    ContentPlaceHolderId="LeftColumn"

    Runat="Server">

    This content appears in the left column

</asp:Content>

<asp:Content ID="Content2"  

    ContentPlaceHolderId="RightColumn"

    Runat="Server">

    This content appears in the right column

</asp:Content>

What this will result in is as follows:

Configuring Master Pages

There is an alternative to associating a content page with a Master Page by using the <%@ Page %> directive. One can associate a Master Page with a content page within the Web application's configuration file. Using the configuration file makes it easier to maintain large Web sites, since they can change the Master Page associated with many content pages in a single location.

You set the Master Page within the <pages> element of a configuration file. (This element appears in the <system.web> section of a configuration file.) For example, the following <pages> element sets the default Master Page to "myMaster.master":

<pages masterPageFile="myMaster.master" />

Two major points to be aware of... The first is that if you want to use the Web.Config file to set the Master Pages, then you should not include the MasterPageFile attribute in the content pages. This is because setting a Master Page within a content page takes precedence over any Master Page set in the configuration file.

Second, the application can contain more than one Web.Config file located in different subfolders that set different Master Pages. In other words, one can override the Master Page set in a Web.Config file within a subfolder by creating a new Web.Config file. This is a really useful and important technique.

Overriding Master Page Properties

One issue that can be encountered almost immediately when working with Master Pages is the issue of how to override such properties as the page title and meta tags of a Master Page in individual content pages. It is common to want to display unique titles for each content page, even when the individual content pages are based on a shared Master Page.

There are multiple ways of overriding the content contained in a Master Page within a particular content page. I'll explore the most common two methods...

If you simply want to change the page title rendered by a Master Page from within a content page, then you can take advantage of the <%@ Page %> directive's Title attribute. This attribute only takes effect when the Master Page uses a server-side HtmlHead control.

For example, the Master Page Code below contains a server-side HtmlHead control.

<%@ Master %>

<html>

<head id="Head1" runat="server">

    <title>Master Title</title>

</head>

<body>

    <form id="form1" runat="server">

    <asp:contentplaceholder

        id="ContentPlaceHolder1"

        runat="server" />

    </form>

</body>

</html>

Notice that the <head> tag includes a runat="server" attribute. This attribute transforms the <head> tag into a server-side HtmlHead control.

The content page below overrides the page title. Notice that the <%@ Page %> directive at the top of this page has a value for its Title attribute. When the page is rendered, the text "Content Page Title" is displayed as the page title.

<%@ Page MasterPageFile="~/TitleMaster.master" Title="Content Page Title" %>

<asp:Content ID="Content1"

    ContentPlaceHolderID="ContentPlaceHolder1"

    Runat="Server">

    Here is some content   

</asp:Content>

If you need to override other attributes of an HTML header, such as the meta tags or style tags, then you can reference the HtmlHead element directly from a content page. The HtmlHead control implements the IPageHeader interface, which includes the following properties:

LinkedStyleSheets - The external style sheets linked to the HTML page.

Metadata - The collection of Metadata tags.

StyleSheet- Represents the styles applied to the HTML page.

Title- The title of the HTML page.

Any of these properties can be easily modified within a content page.

Dynamically loading Master Pages

In the end, I'll take a look at an advanced application of Master Pages, that is to dynamically load different Master Pages at run-time.

There are a couple of circumstances in which dynamically loading Master Pages is useful. First, you might need to co-brand your Web site with one or more partner Web sites. When someone links to your Web site from a partner Web site, you might want to automatically load up a Master Page that matches the look and feel of the partner Web site.

Another situation in which you might want to dynamically load Master Pages is when you want the users of your application to be able to pick a page layout. You can provide your users with a set of standard Master Pages. Users of your application can then select their favorite page layout by selecting their favorite Master Page.

You can dynamically load a Master Page by assigning a value to the MasterPageFile property of the Page object. The value assigned to this property should be a relative path to a valid Master Page file.

There is one important restriction that you must be aware of when using the MasterPageFile property. You can only assign a value to this property before or during the Page PreInit event. The PreInit is the earliest event during the page execution lifecycle. If you attempt to assign a value to this property during a later event, such as the Page Load event, then you'll receive an exception. This restriction makes sense, since different Master Pages will result in different sets of controls being loaded into the page.

To define a Master Page at run-time, simply add the handler for the PreInit even and supply the master page...

<script runat="server">

    Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs)

        MasterPageFile = myMaster.Master

    End Sub

</script>

And all things must come to an end...

The main emphasis in this article was on ASP.Net 2.0 Master Pages. There is no question that Master Pages are my favorite new feature of ASP.Net 2.0. I hope you found this article interesting and informative. I am open for suggestions and remarks, both negative and positive. Feel free to contact me at msalmank@gmail.com.


Tutorial toolbar:  Tell A Friend  |  Add to favorites  |  Feedback  |   


comments powered by Disqus