In ASP.NET 1.1, to give your application a coherent style you were using user controls to make one footer and one header, maybe you make one menu, then you drop those controls into each and every new page you add to your application, it's somehow a good way to make a consistent maintainable UI. Master Pages is an easier solution!
What are Master Pages ?
Master pages let you make a consistent layout for your application, you can make one master page that holds the layout/look & feel and common functionality of your whole application and upon this master page, you can build all the other pages, we call these pages Content Pages. So simply you can build your master page and then build content pages, and while creating the content pages you bind them to the master page you have created before, those two pages are merged at runtime to give you the rendered page.
Master Pages and ContentPlaceHolders
The master page has the extension .master and it's actually an aspx page but with the directive
<%@ Master Language="C#"%>, instead of the standard page directive, almost the attributes of the Master directive are the same as that of the page, you can add any kind of controls the same as you design aspx pages, and it's advisable to use the menu control at your master page ( menu is one of the most nice added controls to ASP.NET 2.0). Every MasterPage should include at least one
ContentPlaceHolder, this control is a placeholder for the content that will be merged at runtime, noting that the content page is just an aspx standard page but you should supply the attribute
MasterPageFile to the page directive to bind the content page to the master page, for example:
<%@ Page Language="C#" MasterPageFile="~/MasterPages/SiteLayout.master"%>
Again, you can design your content page just like any other aspx page adding any static text and server controls.
Content Server Control
Inside the content pages you will find one Content server control added by default, actually when you add controls you add them to the content server control. For example,
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
ContentPlaceHolderID is very important as it decides what content will be bound to which
ContentPlaceHolder on the master page, this is a very nice way to decide the location of where the contents will be displayed; so this way you can have multiple content on one content page and also multiple
ContentPlaceHolders on the master page.
Note: The content pages don't include the common tags as
<Head>,etc. Remember that, that was the same with user controls, as after merging, there should be only one
Programmable Master Pages
Master Pages are programmable. You can make one property to the master page and it will be visible to all the content pages, for example you can get one string like last build or last update from web.config file and provide it as a public property to all the content pages.
Maintainable Master Pages
The best thing about master pages is maintainability as you can now update one master page and this will update all your application pages that refer this master page.
Creating Master Page
- Open Visual Studio 2005.
- Create new ASP.NET Web site, enter name as MasterPagesApp.
- Select Location as File System, and enter the path as D:\WhidbeyWebSites\MasterPagesApp( or any other path ).
- Select the Language you are more comfortable with, for this we will use C#.
- After creating the new Web Site, you will find a page created for you named Default.aspx.
- Delete this page and right click the application from solution explorer. Select Add New Item, select Master Page from installed Visual Studio templates and name it MainLayout, and check the Place code in separate file checkbox; this will create you a code-behind in the language you select, we work here using C#.
- The MainLayOut.master will be open in Source view. You will find this master page directive at the beginning:
<%@ Master AutoEventWireup="true" CodeFile="MainLayOut.master.cs"
Inherits="MainLayOut" Language="C#" >
As you see, the attributes of the
Master directive is common to the ones of the
Page directive, and they are self-descriptive;
CodeFile is the path of the code behind file. It can be VB or C#, note that in one Web Site you can mix between both languages.
Inherits decides the class within the code file to be used.
Language is the language of the code behind file.
AutoEventWireup is so important; for any page there is an automatic way to bind the events to methods in the same aspx file or in code behind, if this attribute is
true ( default value is
true so if it's not mentioned, it will be
true ). Page events are automatically bound to methods that are using naming convention as
Page_event, for example
Page_PreInit (this is the event fired before creating the controls of the page). This has one disadvantage that the standard events of the page should adhere to this naming convention, but if you set it to
false, it will give you more flexibility to use any names for the event handlers, here we should remember the importance of
Handles keyword in VB.NET.
You should also examine the following section:
This server control is the most important for the master pages as this is the zone in which the content pages will be rendered.
- Switch to the Design of the master page, you will get the
ContentPlaceHolder1 shown, now you can design the master page just as any aspx page, so for this practice we'll do a simple master page.
- From Layout menu select Insert Table, Select Template option, then select Header , footer and side, then drag the
ContentPlaceHolder1 control into the right middle cell of the table you have just added.
- Add one label into the left middle cell, and the logo of CodeProject to the upper cell of the table, you should have the same as in the following figure
- Note: You should make all the paths in the master page relative to one folder because the image path will be relative to the rendered content page not for the master page. It's advisable to create one images folder to hold all your images, for example the logo of CodeProject image path is : ./images/codeprojectlogo.JPG. When the content page renders, the path will be evaluated to http://localhost:4843/MasterPagesApp/images/codeprojectlogo.JPG.
- Double click anywhere at the master page. This will open the code behind and will add the
Page_Load event handler. You can write the following code:
Label1.Text = "The Time of Server is: " + DateTime.Now.TimeOfDay;
This will show the time of the server at the label.
Creating Content Page
You should know that the content page is just one aspx page but you bind this page to one master page while you are creating it. To do this, right click your web application from solution explorer and select Add New Item, select Web Form from the installed templates and check Select Maser Page, enter the name of the new page as myContentPage.aspx as in the following figure:
Because you have checked the Select Master Page box, you will get the following dialog to select one master page, this will bind the new aspx page to the selected master page as shown in the following figure:
The page you have just added will open in source view and you will find one entry. Add the
MasterPageFile attribute set to the value of the master page file you have selected before. This should be assigned the value ~/MainLayOut.master. You will also find one Content server control added by default and the attribute
ContentPlaceHolderID assigned to
ContentPlaceHolder1. This is the default value which refers to the
ContentPlaceHolder control at the master page and if you have renamed this control at the master page, you should change it now to the correct ID. This sets the zone in which this content page will be shown as we said before.
Switch to the design view of myContentPage.aspx. You will get the following figure which shows all the master page contents added by all the contents of the master page is dim because they are not editable, only the Content1 will be enabled if you click the white area, and you can now add any controls just as you do for any aspx page.
Double click the white area of Content1, you will get the event handler of
Page_Load, add the following line:
Label1.Text = this.MasterPageFile;
This will show the path of the Master Page file into the label. Actually you can get a reference to the Master Page from a content page by using the
Master property which refers to the page's master page, furthermore you can refer to any control on the master page by using
this.Master.FindControl(string id), this method takes the Id of the control on the master page and returns
Control object, so you should cast to the data type of the control.
Saving Master Page path in web.config
There is one technique by which you can make all the pages comprising your web application as content pages and you can bind all the pages to one master page, this master page that will be a template to your entire application. It's advisable to save the path of this master page into web.config, you can do that using the following:
If you specify a MasterPageFile for your page, it will override your web.config value but the importance of the value of web.config is that it guarantees that all the pages added to your application are bound to this master page file, so if you have more than one master page, you can just change the web.config value, and this will update the whole application pages with no need to recompile. Indeed this technique was a trend at ASP.NET 1.x, as some developers were making all the pages as user controls and pass the id of the user control at the required page URL.
Master Pages are a great addition to ASP.NET 2.0, it's a good way to templatize your application. As we've seen you can change the master page from web.config, and you can access the master page from child content pages by using this Master, thanks to Master Pages!