A comprehensive look at the Master Page

Hi

One of the great additions of ASP.NET 2.0 is Master Page. Master page helps us build a consistent and maintainable UI through out the site.

So how does a Master Page works?

The master Page and the content page merge there content together to create a single aspx page when a request for page arrives, which is using master page. Lets create a simple master page.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!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>
</head>
<body>
    <form id="form1" runat="server">
    <div style="background-color: #ffccff">
        <asp:contentplaceholder id="ContentHeader" runat="server">
        <h1>The Header of the Site</h1>
        </asp:contentplaceholder><div>
       <asp:contentplaceholder id="ContentBody" runat="server">
        Here The body of the Site will be displayed
        </asp:contentplaceholder></div>
    </div>
    </form>
</body>
</html>

Here I have created a simple Master Page, which has two content template (ContentHeader and ContentBody). The master page also contains the Form elsement.

[Note: Master page also contains most of the common tages like Head, HTML, and Body etc.].

Lets us alos create a simple content page derived from this master page.

<%@ Page Language="C#" MasterPageFile="~/MasterPage.master"
Title="Untitled Page" Trace="true" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentBody" Runat="Server">
<p>This is webForm1. </p>
<p></p>
<p>This is contaning the header and Footer form the MasterPage</p>
<p></p>
<p>The body has been overriden by this page</p>
<p><asp:TextBox ID="Label1" runat="server" Text="Textbox"></asp:TextBox></p>

</asp:Content>

Here we have overwritten the contentplaceholder (contentBody). We also have a label inside the content place holder.

At this point of time the master page and the page are two different objects with different hirerchy of children.

The hirerchey of master page is

Master Page
 HTML Form
   ContentBody
   ContentHeader

And the hirerchey of the page is

Page
  Content[ContentBody]
    TextBox

When the times come for master page to work the master page will repalce its content place holders with the conetnt of the page. [Note:Only those which have been overridein in the page, those which have not been overriden in the page will display the HTML of the master page only].

Hence the new hirerchy of the page will be

Page
    Master Page
    HTML Form
      ContentHeader
      ContentBody
        TextBox.

All this work takes place after the preInit event and before the Init event of the Content Page.Remember during this period of the time master page is in control and gives the request for changing the controls etc.] But as soon as the Init event fires the master page becomes a user control for the page and behaves like any other user control of the page. Hence we can think of master page as a master only during design but it is a control during the processing of the page after the Init event of the content page.

[Note: Master page is control in the hirerchy and is derived from UserControl Class].

Hence the preInit event is very important for us if we want to apply the mastr page programatically.

There are many way to attach the master page to the web form. We can specift the master page for the webform in the web.config, @pagedirective or the preInit event. We have to use the MasterPageFile property to set the master page of the web form.

[Note:If you try to set the masterpage property of the page after Init event fires, we will get an exception.]

Most of the time we will want retrive the Master page property from database, cookie etc. so a better way would be to create a base web page and update the preInit event in the base web page. All the pages in our application should derive from this page. If we do not want the end developer to define which master page will be used by which page (considering there will be more than one master page in the site) we can also use HTTP Module to define the master page.

We will also need to interact with the master page for many purposes. There are many ways for interaction of master page and the page. The best way is to take the master page for what it is, a USER CONTROL.

Lets say there is a label [lblText] (with some text) in the master page. The label will have the same text through out the application but some of the pages must be able to override the default text.

When we have more than one master page in the application its best to create a base master page.

Public abstract class BaseMasterPage : MasterPage
{
    public abstract string SomeText
    {
        get;
        set;
    }
}

Now we need to Inherits the master page from this class and override the SomeText property.

To do this lets add a Public property SomeText to the master Page.

Public Property SomeText() As String
  Get
    Return lblText.Text
  End Get
  Set(ByVal value As String)
    lblText.Text = value
  End Set
End Property

Now in the content page we add a  @MasterType directive to the page. The compiler will create strongly typed master property when we have this directive.  We have to provide the TypeName property with the with the class name of the base master page.

Hence you can change the property of the master page through the content page.

Another important thing to know about the master page the series of page load and init event.

Do you know when we are using Master page which event fires first (content page load event or master page load event)? The answer is content page load event fires first. Hence we should not have content page’s load event wait for the load event of the Master Page.

Again note that the Master page Init event fires before the Content page Init event. This is just opposite of the load event firing mechanism.

As we saw earlier that all the title tag, Meta data tags are kept in the master page. But these need to be changed in the content pages. Each content page will (or can) have a different Title, Metadata etc.

We can add the title of the page in the content pages page directive. But what about the other Meta tags. Each page can have its own different Meta tags. We can add a ContentPlaceholder in the head tag of the Master page and override it in the content page. Although this will give some warning in the Visual studio but the project will compile. The warning will be there because the Visual studio accepts all the content placeholder to be inside the Form Tag.

There are some other methods of doing it (using the base class, we will discuss that in some other article).

Another problem that developers might face while using the Master page is breaking URLs due to relative path. If you add an image to the master page like

  <img src="Vikram.gif" alt="Vikram Header" />

This will work fine till the master page and the content page are in the same directory. But if the master page and the content page are ion different directories then you will find broken links. Remember the Master page is only a user control and the not the master of the form. So what is the solution here? ASP.NET will try and rebase the relative URLs in the master page. But remember ASP.NET will only rebase the server control. So if we want any image or link to be rebase we will have make that server side control. (Add the runat=server property to the above image link. The asp.net Run time also rebase the paths mentioned in the head tag.

[Note: If we want the rebasing functionality in some part where the asp.net does not provide rebasing functionality (like style) then we can use the ResolveClientUrl function

background=<%= ResolveClientUrl("logo.gif") %>]

We can also use nested master page(master page acting as the content page to another master page) and also share mastr page across application. We will discuss in some other article.

Hope this helps
Thanks
Vikram


Share this post   Email it |  digg it! |  reddit! |  bookmark it!

Feedback

Posted on 10/11/2006 11:38:49 AM

suppose i used the nested Master page. In the Both Master page i used label control. I want to casting the master page label control in the content page. Can you give me some ideas to me.

Posted on 1/12/2007 12:36:25 PM

“Dynamic Server Controls, Events in content pages that also utilize a MasterPage…”
Basically, for this test I have some dynamic server controls, a dropdown, button and textbox for example…
They are all created in the page_init of the content page as are the event handlers…
Pretty standard stuff, when there is no MasterPage the events are raised as anticipated, when a plain jane MasterPage is added, the dynamic events for said dynamic server controls are not raised…
Can’t seem to make it fly…
Can you shed any light on the subject, possibly a blog article with a functional sample?
Thanks in advance.

Please post your comments:

Name:  
Email (optional): Your email address will not be posted.
URL (optional):
Comments: HTML will be ignored, URLs will be converted to hyperlinks  
Enter the text you see in the box:
 
Copyright © 2006 - 2009 Vikram Lakhotia