Specifying a Master Page
- At the page level: In the content page's @Page directive, you can specify the master page. This is the method used when you create a content page through Visual Studio. A sample page directive is:
Note: ASP.NET resolves the ~ operator to the root of the current application. The ~ operator can be used only in server controls; you cannot use the ~ operator for client elements (that is, HTML elements without the runat="server" specified).
- At the application or folder level: You also can specify the master page to use for content pages in the web.config file. For this, use the web.config file's pages element's masterPageFile attribute. By using this method, one can specify in one place the master page for all the content pages in the Web site or in a particular folder. A sample setting is:
<pages masterPageFile="~/MySite.master" />
Master pages can be nested; for example, a content page refers to a master page which in turn uses another master page. In a typical Web site, the pages are divided into sections; for example, an admin section and a user section. All pages have some common UI that is common for the full Web site. Each section has some UI that is shared just by pages in that section. One can design for this scenario by using nested master pages. The UI common to the full Web site can be put into a parent master page, while each section can have a separate master page that inherits from the parent master page. A sample application is included with this article; it uses nested master pages.
You might need to programmatically access the controls on the master page from content page code. The Page class has a property called Master which, at runtime, references the page's master page, if it has one. But, because the controls are added as protected members, you cannot access them directly using the Master property; use the FindControl method to reference them.
Note: Master pages can contain ContentPlaceHolder controls that contains default content. If you want to get a reference to a control that is inside a ContentPlaceHolder control, first get a reference to the ContentPlaceHolder control and then use its FindControl method. Also, note that if the ContentPlaceHolder contents are overridden by the content page, the controls in ContentPlaceHolder control will not be accessible.
Here, MasterPage is the base class of your master page. To use this property, you can either type-cast it to your master page's class or use the @MasterType directive in the content page. When you use the @MasterType directive, the master page's public members can be directly accessed from the Master property as shown below:
Note: If you set the content page to use a particular master page and you set the @MasterPage directive to a totally different master page class, at runtime you will get an InvalidCastException error.
As you have already seen, you can specify a content page's master page at design time in its @Page directive or in the web.config file. What if you want to set the master page to use at runtime? One might want to change the look of the Web site at runtime if, say, the Web site integrates into different portals or if for different users you present a different look for the Web site. This could be a common requirement.
As the master page is merged into the content page at the page initialization stage, you need to specify the master page in the content page's PreInit event. This event occurs before the page's Load event. Sample code is shown below.
At runtime, the master page merges into the content page and runs in the context of the content page. Now, the question that arises is that if you specify a path on the master page, say the UEL of an image, is this path resolved relative to the location of the master page or the content page? Consider an ASP.NET application with a master page and two content pages that are in different locations as shown.
- Server controls: In server controls on master pages, ASP.NET modifies the URLs of properties that reference external resources. For example, in the above application, if you have an Image Web control on the master page SiteMaster.master and you set its ImageUrl property to "Images/logo.jpg" at runtime ASP.NET will modify the URL so that it resolves correctly in the context of the content page. The behavior is summarized below.
- Plain html: If you have plain HTML elements (that is, HTML controls without the runat="server" specified) on the master page, ASP.NET does not modify this and passes it on as is. This can create problems. For example, consider a plain HTML img on the master page as shown.
- Instead of using plain HTML, use server controls. You can do this by using corresponding Web server controls or by putting runat="server" in the plain HTML, thereby making them HTML server controls. So, in the above example you could change the plain img tags to
- In the master page, for the plain HTML elements, instead of using a relative path, give the full path. This method doesn't result in a performance hit but the drawback here is that it's not a good idea to hardcode the URLs to the full path. So, in the example, the img would be specified as
- Keep your file layout in such a way that the content pages have the same relative position to the master page.