Many Web applications are built so that each page of the application has some similarities. For instance, there may be a common header that is used on every page of your application. Similarly, there may be other common page elements, including navigation sections, advertisements, footers, and more. It really isn’t common to have each of your Web pages have its own unique look and feel. Most people are looking for uniformity in their applications in order to give end users what works, through a multi-paged application.
What is needed for these types of applications is a way to provide a template that can be used by your pages - a sort of visual inheritance (such as you can achieve with Windows Forms). With a feature in ASP.NET 2.0 called master pages, you can employ visual inheritance in your Web applications.
The use of master pages means that you are working with a template file (the master page), which has a .master extension. Once a .master page is created, you can then take a content page, with an .aspx extension, and create an association between the two files. Doing this enables ASP.NET to take these two files and combine them into a single Web page to display in a browser, as illustrated in Figure 20-5.
Figure 20-5
The following sections describe how you make this work. First, you need to create the master page.
The first step is to create a template that will end up being your master page. You can build a master page using any text editor (such as Notepad), but it is far easier to use Visual Studio 2005 or Visual Web Developer, as shown here.
Start within the Solution Explorer. Right-click on the solution and select Add New Item. In the Add New Item dialog you will find the option to add a master page to the solution, as shown in Figure 20-6.
Figure 20-6
Your master page options are quite similar to those when working with a standard .aspx page. You can create master pages to be inline or you can have master pages that utilize the code-behind model. If you wish to use the code-behind model, make sure that you have the "Place code in separate file" check box checked in the dialog - otherwise, leave it blank. Creating an inline master page produces a single .master file. Using the code-behind model produces a .master file in addition to a .master.vb or .master.cs file.
A master page should be built so that it contains one or more content regions that are utilized by the content pages. The following master page example (named Wrox.master) contains two of these content areas:
<%@ Master Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Wrox</title> </head> <body> <form runat="server"> <div> <table cellpadding="3" border="1"> <tr bgcolor="silver"> <td colspan="2"><h1>The Wrox Company Homepage</h1></td> </tr> <tr> <td> <asp:ContentPlaceHolder runat="server"> </asp:ContentPlaceHolder> </td> <td> <asp:ContentPlaceHolder runat="server"> </asp:ContentPlaceHolder> </td> </tr> <tr> <td colspan="2">Copyright 2006 - Wrox</td> </tr> </table> </div> </form> </body> </html>
The first thing to notice is the <% Master %> directive at the top of the page instead of the standard <% Page %> directive. This specifies that this is a master page and cannot be generated without a content page associated with it. It isn’t a page that you can pull up in the browser. In this case, the Master directive simply uses the Language attribute and nothing more, but it has a number of other attributes at its disposal to fine-tune the behavior of the page.
The idea is to code the master page as you would any other .aspx page. This master page contains a simple table and two areas that are meant for the content pages. These areas are defined with the use of the ContentPlaceHolder server control. This page contains two such controls. It is only in these two specified areas where content pages will be allowed to interject content into the dynamically created page (as shown shortly).
The nice thing about working with master pages is that you aren’t limited to working with them in the Code view of the IDE; Visual Studio 2005 also enables you to work with them in Design view as well, as shown in Figure 20-7.
Figure 20-7
In this view, you can work with the master page by simply dragging and dropping controls onto the design surface, just as you would with any typical .aspx page.
Now that there is a master page in your project that you can utilize, the next step is to create a content page that does just that. Right-click on the solution from within the Solution Explorer of Visual Studio 2005 and select Add New Item. This time, though, you are going to add a typical Web Form to the project. However, before you click the Add button, be sure to check the “Select a Master Page” check box in the dialog. This informs VS 2005 that you are going to be building a content page that will be associated with a master page. Doing this pulls up a new dialog, which enables you to select a master page to associate with this new file, as shown in Figure 20-8.
Figure 20-8
In this case, if you have been following along with the example, you should only have a single master page available in the dialog, though it is possible to have as many different master pages as you wish in a single project. Select the Wrox.master page and press the OK button.
The page created will have only a single line of code to it:
<%@ Page Language="VB" MasterPageFile="~/Wrox.master" Title="Untitled Page" %>
This file is quite a bit different from a typical .aspx page. First, there is none of the default HTML code, script tags, and DOCTYPE declarations that are the norm. Second, note the addition of the MasterPageFile attribute in the Page directive. This new attribute makes the association to the master page that will be used for this content page. In this case, it is the Wrox.master file created earlier.
Though there isn’t much to show while in the Source view of Visual Studio when looking at a content page, the real power of master pages can be seen when you switch to the Design view of the same page (see Figure 20-9).
Figure 20-9
This view shows you the entire template and the two content areas that this content page is allowed to deal with. All the grayed-out areas are off-limits and do not allow for any changes from the content page, while the available areas allow you to deal with any type of content you wish. For instance, not only can you place raw text in these content areas, you can also add anything that you would normally place into a typical .aspx page. For an example, create a simple form in one of the content areas and place an image in the other. This code is shown here:
<%@ Page Language="VB" MasterPageFile="~/Wrox.master" Title="My Content Page" %> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Label1.Text = "Hello " & Textbox1.Text End Sub </script> <asp:Content ContentPlaceHolder runat="server"> <b>Enter in your name:<br /> <asp:TextBox runat="server"></asp:TextBox> <asp:Button runat="server" Text="Submit" OnClick="Button1_Click" /> <br /> <br /> <asp:Label runat="server"></asp:Label> </b> </asp:Content> <asp:Content ContentPlaceHolder runat="server"> <asp:Image runat="server" ImageUrl="wrox_logo.gif" /> </asp:Content>
Even from this simple example you can see the differences between a content page and a regular .aspx page. Most important, this page doesn’t contain any <form> element or any of the <html> structure that you would normally see in a typical Web form. All of this content is instead stored inside the master page itself.
This content page contains two Content server controls. Each of these Content server controls maps to a specific <asp:ContentPlaceHolder> control from the master page. This association is made through the use of the ContentPlaceHolderID attribute of the Content control:
<asp:Content ContentPlaceHolder runat="Server"> ... </asp:Content>
Just as with typical .aspx pages, you can create any event handlers you may need for your content page. This particular example uses a button-click event for when the end user submits the form. Running this example produces the results shown in Figure 20-10.
Figure 20-10
As shown in the examples thus far, we have been declaring the master page from the content page through the use of the MasterPageFile attribute of the Page directive:
<%@ Page Language="VB" MasterPageFile="~/Wrox.master" Title="My Content Page" %>
You can apply this attribute to each of your content pages or you can make this declaration in the web.config file of your application, as shown here:
<configuration> <system.web> <pages masterPageFile="~/Wrox.master"></pages> </system.web> </configuration>
From the <pages> node in the web.config file, you declare that all your content pages will use a specific master page through the use of the masterPageFile attribute. Doing this means that your content pages can simply use the following Page directive construction:
<%@ Page Language="VB" Title="My Content Page" %>
The nice thing about making the master page declaration in the web.config file is you don’t have to make this declaration on any of your solution’s content pages; if you later decide to change the template and associate all the content pages to a brand-new master page, you can change every content page instantaneously in one spot.
Doing this has no effect on the regular .aspx pages in your solution. They will still function as normal. Moreover, if you have a content page that you wish to associate with a different master page other than the one specified in the web.config file, then you simply use the MasterPageFile attribute in the Page directive of the page. This will override any declaration that you may have in the web.config file.
Earlier, you saw how to use a basic ContentPlaceHolder control. In addition to using it as shown, you can also create ContentPlaceHolder controls that contain default content:
<asp:ContentPlaceHolder runat="server"> Here is some default content! </asp:ContentPlaceHolder>
For default content, you can again use whatever you want, including any other ASP.NET server controls. A content page that uses a master page containing one of these ContentPlaceHolder controls can then either override the default content - by just specifying content (which overrides the original content declared in the master page) - or keep the default content contained in the control.