ASP.NET Master Page Advice, Tips, and TricksBy Scott Mitchell
Master pages are an important part of any ASP.NET website. In a nutshell, a master page allows the page developer to define a website template, indicating what portions of the template are to remain fixed across pages that use the template and what regions of the template are customizable on a page-by-page basis. Having the site design and layout centralized in one (or more) master pages makes it easy to add new pages to the site that inherit the same look and feel and greatly simplifies changing the site design or adding or removing content that is common to all pages, such as content in the
This article presents advice for using master pages, along with assorted tips and tricks that I've picked up over the years in using master pages. Read on to learn more! And if you have additional recommendations and advice on using master pages, please don't hesitate to drop me a line and I'll be happy to add your insight to this article.
When Starting a New Website Create a Master Page Before Creating Any Other Web Pages
Because the master page defines the look and feel for the site, it is only natural to think that the master page need not be created until the site's design has been completed. For many projects, the site's design is created by a graphic artist, either within the company or outsourced to another firm. Consequently, it's not uncommon for development work to begin prior to the site design being completed, leading ASP.NET developers to not create the master page until the site design is ready.
When starting a new ASP.NET website the very first thing I do is create a master page, regardless of whether the site design is ready. If the site design is ready, then the master page can be implemented with the design. If it's not yet complete, then just use the master page's default markup. Don't worry about having an ugly or incomplete master page - you can always come back and update it once the site design is ready. The reasoning for creating a master page right off the bat, regardless of whether the site design is ready, is because Visual Studio makes it very easy to add a new content page to the site, but requires that you jump through more hoops to take an ASP.NET page that does not use a master page and convert it into a content page.
When using the Web Site Project model (WSP), adding a new content page to the website is simply a matter of checking the "Select master page" checkbox; for Web Application Projects (WAPs) it's as easy as adding an item of type Web Content Form. Both approaches display a dialog box that prompts you to select the new content page's master page. If you have an existing ASP.NET page that does not use a master page, converting it into a content page involves removing the markup in the content page that is defined in the master page, adding appropriately named Content controls, and moving the page-specific markup into the appropriate Content controls. It's not rocket science, but it is certainly more work and not as quick or easy as checking a checkbox or selecting the Web Content Form item type.
|Web Site Projects (WSPs) vs. Web Application Projects (WAPs)|
Visual Studio supports two styles of ASP.NET projects: Web Site Projects (WSPs) and Web Application Projects (WAPs). WSPs are created by going to the File menu and choosing
to create a New Website. They use automatic compilation (by default), meaning that the code in the pages' code-behind classes is automatically compiled when the page is
first visited from a browser. Furthermore, the website project's files are defined by the files that exist within the website's folder structure.
WAPs are created by going to the File menu, choosing New Project, and creating a project of type ASP.NET Web Application Project. For a WAP, the code in the pages' code-behind classes is compiled explicitly from within Visual Studio by going to the Build menu. Also, the files that makeup the project are defined by a project file.
There are some subtle and not so subtle differences for the developer experience depending on the project model being used. For instance, creating a content page from a WSP entails checking the "Select master page" checkbox, whereas with a WAP you must choose a different item type, Web Content Form, as there is no "Select master page" checkbox to be found. For more background on these two project types check out the "Taking a Trip Down Memory Lane" section in Determining What Files Need To Be Deployed tutorial, which is one of 16 tutorials in my ASP.NET Hosting Tutorials on www.asp.net.
Do Not Name Your Master Page
When creating a master page in a website that uses the Web Site Project model Visual Studio will suggest the name
MasterPage.master. If you create a the master page using this suggested name then the master page's code-behind class will also be named
MasterPageand will have the following definition:
Note that the master page's code-behind class derives from the
MasterPage class in the
System.Web.UI namespace. These two identical names do not cause
a conflict because the master page's code-behind class and the
MasterPage class in the
System.Web.UI namespace are in two difference namespaces.
However, it can lead to some difficulties if you need to get a strongly-typed reference to the master page from one of the content pages. While this annoyance
is a minor one, I find it best to name the master page something else, like
Site.master, and to avoid this confusion altogether. (Coincidentally, Visual Studio
suggests the name
Site.master when adding a new master page to a WAP. Why this same convention isn't used for WSPs is beyond me.)
Supply Default Content in the Master Page's ContentPlaceHolder Controls
The master page defines the markup that is fixed across all content pages along with what regions can be customized on a page-by-page basis. The ContentPlaceHolder control is what indicates a region that can be customized by a content page, and a master page can include zero to many such controls. When a new content page is added to the site, Visual Studio adds a Content control in the content page for each ContentPlaceHolder defined in the master page, inviting us (the page developer) to define the page-specific content for each region.
Did you know that these Content controls in the content page are optional? A content page need only define Content controls for the ContentPlaceHolders it wants to provide custom content for. What's more, the ContentPlaceHolder control in the master page can include content within it, as well, and this default content is used if the content page does not provide a Content control that overrides it.
The last paragraph may be a bit confusing, as I used the word "content" nine times! A simple example should clear things up. Consider a master page with two ContentPlaceHolder
SecondContentPlaceHolder. Typically, the ContentPlaceHolder controls are defined without specifying any inner
content, like so:
With the idea being that a content page would define two Content controls that define the page-specific content for these regions. For example, a content page might contain the following markup:
Note that there are two Content controls,
Content2, which define the content that is injected into the master page's
SecondContentPlaceHolder ContentPlaceHolder controls, respectively. The screen shot below shows this content page when viewed through a browser.
However, we could alter the master page to define default content for these two ContentPlaceHolders. The following updated master page markup illustrates this:
If we visit the content page through a browser again the output is the same as shown in the above screen shot. However, if we remove one of the Content controls from the
content page then its output is replaced by the default content defined in the corresponding ContentPlaceHolder. For example, if we remove the
control that references the
SecondContentPlaceHolder ContentPlaceHolder our content page markup will look like the following:
Now when this page is viewed through a browser we see, "I have nothing interesting to say" at the top of the page - the content defined within the content page - but
we see the default markup for the
SecondContentPlaceHolder ContentPlaceHolder, "This is the second content place holder!"
This default markup functionality of the ContentPlaceHolder control is useful in scenarios where virtually every page in the site has fixed content in one area, but there are one or two pages that need to customize the content in that region. In such a case you would do the following:
- Add a ContentPlaceHolder to the master page to indicate the region that is fixed for the majority of the pages, but needs to be customized for a small subset of pages.
- Enter the markup that is common to the majority of the pages within the ContentPlaceHolder.
- In those ASP.NET pages that use the same, default content, remove the corresponding Content control from the page's markup.
- For those pages where the content is unique, create a corresponding Content control and define the unique content within.
Use Web Controls and the Tilde Character (
~) for Specifying URLs for Links and Images
When adding images or links to the master page, you may be tempted to use vanilla HTML elements, like the
<img>element. For example, to add a link to the homepage from the master page you might use HTML like so:
While this markup will work fine for content pages in the same folder as the master page, things do not work as expected for content pages in different folders. Consider what
would happen if the master page was in the root folder of the site, but one of its content pages was in a subfolder named
Folder1. The HTML rendered in the
content page in
Folder1 would be exactly the same markup shown above, namely:
<a href="Default.aspx">Return To Homepage</a>. Consequently,
if a user clicked that link they would be taken to the page
Folder1/Default.aspx and not to the
Default.aspx page in the root directory,
which was the intent. To remedy this we can use a HyperLink control in place of the
<a> HTML element along with the tilde character (
"root" the URL.
NavigateUrl value of
~/Default.aspx causes the HyperLink control to generate a URL that is relative to the folder of the content page.
A content page in the root directory of the site will render HTML like
<a href="Default.aspx">Return To Homepage</a>, whereas a content page in
a subfolder (such as
Folder1) will render HTML like:
<a href="../Default.aspx">Return To Homepage</a>.
This same issue applies with
<img> elements. Rather than using
<img>, use an
<asp:Image> Web control and root
the URL to the image via the
@MasterType Directive To Get a Strongly-Typed Master Page Reference
All content pages have a loosely-typed reference to their master pages via the
Page.Masterproperty. If you have defined public methods or properties in your master page and want to access them from a content page you'll need to get a strongly-typed reference to your master page from the content page. One option is to cast the loosely-typed reference to a strongly-typed one. The following code snippet shows how to cast the
Page.Masterproperty to the master page type
An even better approach is to use the
@MasterType directive. The
@MasterType directive is a directive you add to the content page's
that indicates it's master page. The presence of this directive instructs the ASP.NET compiler to add a strongly-typed property named
Master to the page. The
following snippet from the declarative portion of a content page shows the
@MasterType directive in action:
With this directive in place the
Page.Master property remains a loosely-typed reference to the master page, but the
Master property (without
Page.) is a strongly-typed reference. (Confusing, I know.) But with this directive and the
Master property you can access the public methods
and properties of your master page without having to cast the
For more information on content and master page interaction, see the tutorials Interacting with the Master Page from the Content Page and Interacting with the Content Page from the Master Page. Also refer to Scott Allen's article, Master Pages: Tips, Tricks, and Traps.
Prefer Using Nested Master Pages Over Separate Master Pages
Most of the websites I've worked on have had an overarching site design with various sections of the site that differ slightly from one another. I've worked on an eCommerce site that had a common layout among all pages - a menu at the top, information about the user and their cart in the upper right corner, legalese at the bottom, section-specific links on the left, and so on - but had minor customizations for the various sections. There were a total of four logical sections: general, non-product-specific pages; general products; logoed merchandise; and order fulfillment pages. The background image used at the top of the page differed among the four sections, and there were different links and slight layout differences in the upper right corner.
One approach to managing these differences would be to have four master pages in the project, one for each section. The problem with this approach is that it involves a lot of repeated markup and code, as more than 90% of the site design and layout markup between the sections was identical. As a result, any changes to the overarching design would require modifying the markup in all four master pages.
A better approach is to use nested master pages. Much like how an ASP.NET page can have a master page, a master page may also be assigned a master page. Such master pages are said to be nested. With nested master pages you could define a "root" master page that defines the markup and layout that is common to all sections and then create a nested master page for each of the four sections. The content pages in each section would then use the appropriate nested master page. The net benefit of this approach is that the overarching site design markup is consolidated into one "root" master page and the nested master pages contain only the variations among the sections. This makes it much easier to modify the site-wide design and have those changes instantaneously applied to all sections.
Master pages offer ASP.NET page developers an easy way to define a site-wide design and to have it apply to all content pages. All ASP.NET websites should include a master page and that master page should be the first thing added to the project. This article dispensed some master pages advice along with some tips and tricks. If you have additional advice or tips regarding master pages, please share them with your fellow readers by sending them to me. I'll happily add such recommendations to this article.