Working with Master Pages

 

Working with Master Pages

As a matter of fact, ASP.NET and Microsoft Visual Studio .NET greatly simplified the process of authoring Web pages and Web sites and made it affordable to a wide range of people with different skills. However, after a few months of real-world experience, many developers recognized that something was missing in the ASP.NET approach to page authoring. While building simple sites is easy, architecting real-world sites with hundreds of complex and rich pages still requires additional work and, more important, key decisions to be made without guidance.

Almost all Web sites use a similar graphical layout for all their pages. This doesn't happen by chance it grows out of accepted guidelines for design and usability. A consistent layout is characteristic of all cutting-edge Web sites, no matter how complex. For some Web sites, the layout consists of the header, body, and footer; for others, it is a more sophisticated aggregation of navigational menus, buttons, and panels that contain and render the actual content. Needless to say, manual duplication of code and HTML elements is simply out of the question. Making code automatically reusable clearly represents a better approach, but how do you implement it in practice?

Authoring Rich Pages in ASP.NET 1.x

In ASP.NET 1.x, the best approach to authoring pages with a common layout is to employ user controls. User controls are aggregates of ASP.NET server controls, literal text, and code. (We'll cover user controls in my other recent book, Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics [Microsoft Press, 2005], which is published as a companion volume to this book.) The ASP.NET runtime exposes user controls to the outside world as programmable components. The idea is that you employ user controls to tailor your own user interface components and share them among the pages of the Web site. For example, all the pages that need a navigational menu can reference and configure the user control that provides that feature.

What's Good About User Controls

User controls are like embeddable pages. Turning an existing ASP.NET page into a user control requires only a few minor changes. User controls can be easily linked to any page that needs their services. Furthermore, changes to a user control's implementation do not affect the referencing page and only require you (or the runtime) to recompile the user control into an assembly.

Note 

In ASP.NET, user controls make the use of classic ASP include files obsolete. A typical ASP include file contains either static or dynamic content for the portion of the page it represents. There's no object orientation in this approach, making thoughtful design and easy maintainability very difficult, if not impossible, for very large Web sites. In addition, include file tags opened in one file are frequently closed in another file. This situation makes WYSIWYG designer support virtually impossible.

What's Bad About User Controls

If you change the internal implementation of the user control, no referencing page will be affected. However, if you alter any aspect of the control's public interface (such as the class name, properties, methods, or events), all the pages that reference the control must be updated. This means you must manually retouch all the pages in the application that use the control. Then you must recompile these pages and deploy the assemblies. In addition, the next time a user views each page, the ASP.NET runtime will take a while to respond because the dynamic assembly for the page must be re-created.

Architecturally speaking, the solution based on user controls works just fine. In practice, though, it is not a very manageable model for large-scale applications its effectiveness decreases as the complexity of the application (the number of pages involved) increases. If your site contains hundreds of pages, handling common elements through user controls can quickly become inefficient and unmanageable.

Visual Inheritance

ASP.NET pages are built as instances of special classes code-behind or code file classes. Because pages are ultimately classes, what happens if you stuff part of the common UI in some base class and inherit new pages from there? This approach resembles the visual inheritance feature that Windows Forms developers have been familiar with for a long time.

Pure visual inheritance a l Windows Forms is impractical in ASP.NET. This is because ASP.NET pages are made of code and markup. The markup determines the position of the controls, while code adds logic and functionality. Building predefined graphic templates in the base class doesn't pose issues, but how would you import those standard UI blocks in derived pages, and, more important, how would you merge those with controls local to the derived page?

In Windows Forms, controls have an absolute position that the designer reproduces, making it easy for developers to insert new controls anywhere. Web Forms, though, typically use relative positioning, which leads to either of the next two design choices. Option one is to supply predefined and named UI blocks in base classes and have derived classes load them in matching placeholders. Option two involves using master pages as defined in ASP.NET 2.0. To implement the former technique do the following:

  1. Derive your page from a base class that knows how to create special UI blocks such as toolbars, headers, and footers. Each of these UI blocks has a unique name.

  2. Add <asp:placeholder> controls to the derived page whose ID matches any of the predefined names. The base class contains the code to explore the control's tree and expand placeholders with predefined UI blocks.

This approach exploits inheritance but provides no WYSIWYG facilities and forces you to create UI blocks in code-only mode with no markup. This option is demonstrated in the companion code, but it should be considered only for ASP.NET 1.x applications. The second option mentioned using master pages is described in the following section.

Writing a Master Page

In ASP.NET 2.0, a master page is a distinct file referenced at both the application level and the page level that contains the static layout of the page. Regions that each derived page can customize are referenced in the master page with a special placeholder control. A derived page is simply a collection of blocks the runtime will use to fill the holes in the master. True visual inheritance la Windows Forms is not a goal of ASP.NET 2.0 master pages. The contents of a master page are merged into the content page, and they dynamically produce a new page class that is served to the user upon request. The merge process takes place at compile time and only once. In no way do the contents of the master serve as a base class for the content page.

What's a Master Page, Anyway?

A master page is similar to an ordinary ASP.NET page except for the top @Master directive and the presence of one or more ContentPlaceHolder server controls. A ContentPlaceHolder control defines a region in the master page that can be customized in a derived page. A master page without content placeholders is technically correct and will be processed correctly by the ASP.NET runtime. However, a placeholderless master fails in its primary goal to be the supertemplate of multiple pages that look alike. A master page devoid of placeholders works like an ordinary Web page but with the extra burden required to process master pages. Here is a simple master page:

<%@ Master Language="C#" CodeFile="Simple.master.cs" Inherits="Simple" %> <html> <head runat="server">     <title>Hello, master pages</title> </head> <body>     <form  runat="server">         <asp:Panel  runat="server"             BackImageUrl="Images/SkyBkgnd.png" Width="100%">             <asp:Label  runat="server"                 Text="Programming ASP.NET 2.0" />         </asp:Panel>         <asp:contentplaceholder  runat="server">          <!-- derived pages will define content for this placeholder -->        </asp:contentplaceholder>         <asp:Panel  runat="server"             BackImageUrl="Images/SeaBkgnd.png">             <asp:Label  runat="server"                  Text="Dino Esposito" />         </asp:Panel>     </form> </body> </html> 

As you can see, the master page looks like a standard ASP.NET page. Aside from the identifying @Master directive, the only key differences are ContentPlaceHolder controls. A page bound to this master automatically inherits all the contents of the master (the header and footer, in this case) and can attach custom markup and server controls to each defined placeholder. The content placeholder element is fully identified by its ID property and normally doesn't require other attributes.

The @Master Directive

The @Master directive distinguishes master pages from content pages and allows the ASP.NET runtime to properly handle each. A master page file is compiled to a class that derives from the MasterPage class. The MasterPage class, in turn, inherits UserControl. So, at the end of the day, a master page is treated as a special kind of ASP.NET user control.

The @Master supports quite a few attributes. For the most part, though, they are the same attributes that we reviewed in Chapter 3 for the @Page directive. Table 6-1 details the attributes that have a special meaning to master pages.

Table 6-1: Attributes of the @Master Directive

Attribute

Description

ClassName

Specifies the name for the class that will be created to render the master page. This value can be any valid class name but should not include a namespace. By default, the class name for simple.master is ASP.simple_master.

CodeFile

Indicates the URL to the file that contains any source code associated with the master page.

Inherits

Specifies a code-behind class for the master page to inherit. This can be any class derived from MasterPage.

MasterPageFile

Specifies the name of the master page file that this master refers to. A master can refer to another master through the same mechanisms a page uses to attach to a master. If this attribute is set, you will have nested masters.

The master page is associated with a code file that looks like the following:

public partial class Simple : System.Web.UI.MasterPage {     protected void Page_Load(object sender, EventArgs e) {         ...     }      } 

The @Master directive doesn't override attributes set at the @Page directive level. For example, you can have the master set the language to Visual Basic .NET and one of the content pages can use C#. The language set at the master page level never influences the choice of the language at the content page level. You can use other ASP.NET directives in a master page for example, @Import. However, the scope of these directives is limited to the master file and does not extend to child pages generated from the master.

Note 

You can create master pages programmatically. You build your own class and make it inherit MasterPage. Then you create .master files in which the Inherits attribute points to the fully qualified name of your class. Rapid application development (RAD) designers such as the one embedded in Microsoft Visual Studio .NET 2005 use this approach to create master pages.

The ContentPlaceHolder Container Control

The ContentPlaceHolder control acts as a container placed in a master page. It marks places in the master where related pages can insert custom content. A content placeholder is uniquely identified by an ID. Here's an example:

<asp:contentplaceholder runat="server"  /> 

A content page is an ASP.NET page that contains only <asp:Content> server tags. This element corresponds to an instance of the Content class that provides the actual content for a particular placeholder in the master. The link between placeholders and content is established through the ID of the placeholder. The content of a particular instance of the Content server control is written to the placeholder whose ID matches the value of the ContentPlaceHolderID property, as shown here:

<asp:Content runat="server" contentplaceholder>     ... </asp:Content> 

In a master page, you define as many content placeholders as there are customizable regions in the page. A content page doesn't have to fill all the placeholders defined in the bound master. However, a content page can't do more than just fill placeholders defined in the master.

Note 

A placeholder can't be bound to more than one content region in a single content page. If you have multiple <asp:Content> server tags in a content page, each must point to a distinct placeholder in the master.

Specifying Default Content

A content placeholder can be assigned default content that will show up if the content page fails to provide a replacement. Each ContentPlaceHolder control in the master page can contain default content. If a content page does not reference a given placeholder in the master, the default content will be used. The following code snippet shows how to define default content:

<asp:contentplaceholder runat="server" >     <!-- Use the following markup if no custom         content is provided by the content page -->     ... </asp:contentplaceholder> 

The default content is completely ignored if the content page populates the placeholder. The default content is never merged with the custom markup provided by the content page.

Note 

A ContentPlaceHolder control can be used only in a master page. Content placeholders are not valid on regular ASP.NET pages. If such a control is found in an ordinary Web page, a parser error occurs.

Writing a Content Page

The master page defines the skeleton of the resulting page. If you need to share layout or any UI block among all the pages, placing it in a master page will greatly simplify management of the pages in the application. You create the master and then think of your pages in terms of a delta from the master. The master defines the common parts of a certain group of pages and leaves placeholders for customizable regions. Each content page, in turn, defines what the content of each region has to be for a particular ASP.NET page. Figure 6-1 shows how to create a content page in Visual Studio .NET 2005.

image from book
Figure 6-1: Adding a content page to a Visual Studio .NET 2005 project.

The Content Control

The key part of a content page is the Content control a mere container for other controls. The Content control is used only in conjunction with a corresponding ContentPlaceHolder and is not a standalone control. The master file that we considered earlier defines a single placeholder named PageBody. This placeholder represents the body of the page and is placed right below an HTML table that provides the page's header. Figure 6-2 shows a sample content page based on the aforementioned master page.

image from book
Figure 6-2: A preview of the content page. Notice the layout of the master page grayed out in the background.

Let's take a look at the source code of the content page:

<%@ Page Language="C#" MasterPageFile="Simple.master"          CodeFile="HelloMaster.aspx.cs" Inherits="HelloMaster" %> <asp:Content  ContentPlaceHolder Runat="Server">     <h1>Welcome to this page!</h1>     <h3>The rest of the page is kindly offered by our sponsor         page-the master!</h3> </asp:Content> 

The content page is the resource that users invoke through the browser. When the user points her or his browser to this page, the output in Figure 6-3 is shown.

image from book
Figure 6-3: The sample page in action.

The replaceable part of the master is filled with the corresponding content section defined in the derived pages. A content page that is, a page bound to a master is a special breed of page in that it can only contain <asp:Content> controls. A content page is not permitted to host server controls outside of an <asp:Content> tag.

Let's explore the attachment of pages to masters in a bit more detail.

Attaching Pages to a Master

In the previous example, the content page is bound to the master by using the MasterPageFile attribute in the @Page directive. The attribute points to a string representing the path to the master page. Page-level binding is just one possibility although it is the most common one.

You can also set the binding between the master and the content at the application or folder level. Application-level binding means that you link all the pages of an application to the same master. You configure this behavior by setting the Master attribute in the <pages> element of the principal web.config file:

<configuration>     <system.web>         <pages master="MyApp.master" />     </system.web> </configuration> 

If the same setting is expressed in a child web.config file a web.config file stored in a site subdirectory all ASP.NET pages in the folder are bound to a specified master page.

Note that if you define binding at the application or folder level, all the Web pages in the application (or the folder) must have Content controls mapped to one or more placeholders in the master page. In other words, application-level binding prevents you from having (or later adding) a page to the site that is not configured as a content page. Any classic ASP.NET page in the application (or folder) that contains server controls will throw an exception.

Device-Specific Masters

Like all ASP.NET pages and controls, master pages can detect the capabilities of the underlying browser and adapt their output to the specific device in use. ASP.NET 2.0 makes choosing a device-specific master easier than ever. If you want to control how certain pages of your site appear on a particular browser, you can build them from a common master and design the master to address the specific features of the browser. In other words, you can create multiple versions of the same master, each targeting a different type of browser.

How do you associate a particular version of the master and a particular browser? In the content page, you define multiple bindings using the same MasterPageFile attribute, but you prefix it with the identifier of the device. For example, suppose you want to provide ad hoc support for Microsoft Internet Explorer and Netscape browsers and use a generic master for any other browsers that users employ to visit the site. You use the following syntax:

<%@ Page masterpagefile="Base.master"     ie:masterpagefile="ieBase.master"     netscape6to9:masterpagefile="nsBase.master" %> 

The ieBase.master file will be used for Internet Explorer; the nsBase.master, on the other hand, will be used if the browser belongs to the Netscape family, versions 6.x to 9.0. In any other case, a device-independent master (Base.master) will be used. When the page runs, the ASP.NET runtime automatically determines which browser or device the user is using and selects the corresponding master page, as shown in Figure 6-4.

image from book
Figure 6-4: Browser-specific master pages.

The prefixes you can use to indicate a particular type of browser are those defined in the ASP.NET configuration files for browsers. Table 6-2 lists the most commonly used Brower IDs.

Table 6-2: ID of Most Common Browsers

Browser ID

Browser Name

IE

Any version of Internet Explorer

Netscape3

Netscape Navigator 3.x

Netscape4

Netscape Communicator 4.x

Netscape6to9

Any version of Netscape higher than 6.0

Mozilla

Firefox

Opera

Opera

Up

Openwave-powered devices

It goes without saying that you can distinguish not only between up-level and down-level browsers but also between browsers and other devices, such as cellular phones and personal digital assistants (PDAs). If you use device-specific masters, you must also indicate a device-independent master.

Warning 

Browser information is stored differently in ASP.NET 1.x and ASP.NET 2.0. In ASP.NET 1.x, you find it in the <browserCaps> section of the machine.config file. In ASP.NET 2.0, it is stored in text files with a .browser extension located in the Browsers folder under the ASP.NET installation path on the Web server: WINDOWS%\Microsoft.NET\Framework\[version]\Config\Browsers.

Setting the Title of a Page

As a collection of <asp:Content> tags, a content page is not allowed to include any markup that can specify the title of the page. Using the <title> tag is possible in the master page, but the master page by design works as the base for a variety of pages, each requiring its own title. The trick to setting the title is in using the Title property of the @Page directive in the content page:

<@Page MasterPageFile="simple.master" Title="Hello, master" %> 

Note, though, the setting of the title of the page is possible only if the <title> or the <head> tag in the master is flagged as runat=server.

Processing Master and Content Pages

The use of master pages slightly changes how pages are processed and compiled. For one thing, a page based on a master has a double dependency on the .aspx source file (the content page) and on the .master file (the master page). If either of these pages changes, the dynamic page assembly will be re-created. Although the URL that users need is the URL of the content page, the page served to the browser results from the master page fleshed out with any replacement provided by the content page.

Compiling Master Pages

When the user requests an .aspx resource mapped to a content page that is, a page that references a master the ASP.NET runtime begins its job by tracking the dependency between the source .aspx file and its master. This information is persisted in a local file created in the ASP.NET temporary files folder. Next, the runtime parses the master page source code and creates a Visual Basic .NET or C# class, depending on the language set in the master page. The class inherits MasterPage, or the master's code file, and is then compiled to an assembly.

If multiple .master files are found in the same directory, they are all processed at the same time. Thus a dynamic assembly is generated for any master files found, even if only one of them is used by the ASP.NET page whose request triggered the compilation process. Therefore, don't leave unused master files in your Web space they will be compiled anyway. Also note that the compilation tax is paid only the first time a content page is accessed within the application. When a user accesses another page that requires the second master, the response is faster because the previously compiled master is cached.

Serving the Page to Users

As mentioned, any ASP.NET page bound to a master page must have a certain structure no server controls or literal text are allowed outside the <asp:Content> tag. As a result, the layout of the page looks like a plain collection of content elements, each bound to a particular placeholder in the master. The connection is established through the ID property. The <asp:Content> element works like a control container, much like the Panel control of ASP.NET or the HTML <div> tag. All the markup text is compiled to a template and associated with the corresponding placeholder property on the master class.

The master page is a special kind of user control with some templated regions. It's not coincidental, in fact, that the MasterPage class inherits from the UserControl class. Once instantiated as a user control, the master page is completed with templates generated from the markup defined in the content page. Next, the resulting control is added to the control tree of the current page. No other controls are present in the final page except those brought in by the master. Figure 6-5 shows the skeleton of the final page served to the user.

image from book
Figure 6-5: The structure of the final page in which the master page and the content page are merged.

Nested Master Pages

So far we've seen a pretty simple relationship between a master and a collection of content pages. However, the topology of the relationship can be made as complex and sophisticated as needed. A master can, in fact, be associated with another master and form a hierarchical, nested structure. When nested masters are used, any child master is seen and implemented as a plain content page in which extra ContentPlaceHolder controls are defined for an extra level of content pages. Put another way, a child master is a kind of content page that contains a combination of <asp:Content> and <asp:ContentPlaceHolder> elements. Like any other content page, a child master points to a master page and provides content blocks for its parent's placeholders. At the same time, it makes available new placeholders for its child pages.

Note 

There's no architectural limitation in the number of nesting levels you can implement in your Web sites. Performance-wise, the depth of the nesting has a negligible impact on the overall functionality and scalability of the solution. The final page served to the user is always compiled on demand and never modified as long as dependent files are not touched.

Let's expand on the previous example to add an intermediate master page. The root master page named parent.master defines the header, the footer, and a replaceable region. Except for the class names, the source code is identical to the example we considered earlier. Let's have a closer look at the intermediate master named content.master:

<%@ Master Language="C#" MasterPageFile="Parent.master"     CodeFile="Content.master.cs" Inherits="ContentMaster" %> <asp:Content Runat="Server" ContentPlaceHolder >     <table width="100%"><tr>         <td>             <h1>Welcome to this page!</h1>             <h3>The rest of the page is kindly offered by our                 sponsor page-the master!</h3>         </td>         <td align="center">             <h2>Select Your Favorite Chapter</h2>             <asp:ContentPlaceHolder runat="server"  />         </td>     </tr></table> </asp:Content> 

As you can see, the master contains both a collection of <asp:Content> and <asp:ContentPlaceHolder> tags. The top directive is that of a master but contains the MasterPageFile attribute, which typically characterizes a content page.

The content.master resource is not directly viewable because it contains a virtual region. If you're familiar with object-oriented programming (OOP) terminology, I'd say that an intermediate master class is much like an intermediate virtual class that overrides some methods on the parent but leaves other abstract methods to be implemented by another derived class. Just as abstract classes can't be instantiated, nested master pages can't be viewed through a browser. In any case, the content.master resource is undoubtedly a master class, and its code file contains a class that inherits from MasterPage.

Warning 

Because Visual Studio .NET 2005 doesn't support visual editing of nested master pages, you have to create an intermediate master page as a content page, change the top directive to @Master, remove the Title attribute and, last but not least, change the base class of the code file to MasterPage.

The following code illustrates a content page that builds on two masters:

<%@ Page Language="C#" MasterPageFile="Content.master"          CodeFile="ViewBook.aspx.cs" Inherits="ViewBook"          Title="Book Viewer" %> <asp:Content ContentPlaceHolder Runat="Server">     <asp:DropDownList runat="server">         ...     </asp:DropDownList><br />     <asp:Button runat="server" Text="Read ..." /> </asp:Content> 

Figure 6-6 shows the final results.

image from book
Figure 6-6: The page results from the combination of two master pages.

Admittedly, there's nothing in the figure that clearly indicates the existence of two masters; for your information, the innermost master controls the leftmost area where the drop-down list is laid out. This means that writing another page that offers an alternative technique to find a chapter is particularly easy. Have a look at the code and Figure 6-7:

<%@ Page Language="C#" MasterPageFile="Content.master"     CodeFile="SearchBook.aspx.cs" Inherits="SearchBook" %> <asp:Content ContentPlaceHolder Runat="Server">     <asp:TextBox runat="server" Text="[Enter keywords]" />     <asp:LinkButton runat="server" Text="Search ..." /> </asp:Content> 

image from book
Figure 6-7: A slightly different page requires slightly different code!

A sapient use of master and content pages leads straight to an obvious conclusion: slightly different pages require slightly different code.

Programming the Master Page

You can use code in content pages to reference properties, methods, and controls in the master page, with some restrictions. The rule for properties and methods is that you can reference them if they are declared as public members of the master page. This includes public page-scope variables, public properties, and public methods.

Exposing Master Properties

To give an identity to a control in the master, you simply set the runat attribute and give the control an ID. Can you then access the control from within a content page? Not directly. The only way to access the master page object model is through the Master property. Note, though, that the Master property of the Page class references the master page object for the content page. This means that only public properties and methods defined on the master page class are accessible.

The following code enhances the previous master page to make it expose the text of the header as a public property:

public partial class SimpleWithProp : System.Web.UI.MasterPage {     protected void Page_Load(object sender, EventArgs e)     {     }     public string TitleBoxText     {         get { return TitleBox.Text; }         set { TitleBox.Text = value; }     } } 

The header text of Figure 6-3 (shown earlier) is represented by a Label control named TitleBox. The control's protection level makes it inaccessible from the outside world, but the public property TitleBoxText defined in the preceding code represents a public wrapper around the Label's Text property. In the end, the master page has an extra public property through which programmers can set the text of the header.

Invoking Properties on the Master

The Master property is the only point of contact between the content page and its master. The bad news is that the Master property is defined to be of type MasterPage; as such, it doesn't know anything about any property or method definition specific to the master you're really working with. In other words, the following code wouldn't compile because no TitleBoxText property is defined on the MasterPage class:

public partial class HelloMaster : System.Web.UI.Page {     protected void Page_Load(object sender, EventArgs e)     {         Master.TitleBoxText = "Programming ASP.NET-version 2.0";     } } 

What's the real type behind the Master property?

The Master property represents the master page object as compiled by the ASP.NET run-time engine. This class follows the same naming convention as regular pages ASP.XXX_master, where XXX is the name of the master file. Developers can override the default class name by setting the ClassName attribute on the @Master directive. The attribute lets you assign a user-defined name to the master page class:

<%@ Master Inherits="SimpleWithProp"   Classname="MyMaster" %> 

In light of this, to be able to call custom properties or methods, you must first cast the object returned by the Master property to the actual type:

((ASP.MyMaster)Master).TitleBoxText = "Programming ASP.NET-version 2.0"; 

Interestingly enough, Visual Studio .NET 2005 provides some facilities to let you identify the right dynamically generated type already at design time. (See Figure 6-8.)

The ASP namespace is the system namespace that all system dynamically defined types belong to. In Visual Studio .NET 2005, that namespace is properly recognized and handled by Microsoft IntelliSense. That was not the case with the previous version of Visual Studio .NET.

image from book
Figure 6-8: Visual Studio .NET 2005 pops up names of classes that will be created only during the page execution.

The @MasterType Directive

By adding the @MasterType directive in the content page, you can avoid all the casting just shown. The @MasterType informs the compiler about the real type of the Master property. The Master property is declared of the right type in the dynamically created page class, and this allows you to write strong-typed code, as follows:

<%@ Page Language="C#" MasterPageFile="SimpleWithProp.master"     CodeFile="HelloMasterType.aspx.cs" Inherits="HelloMasterType" %> <%@ MasterType VirtualPath="SimpleWithProp.master" %> 

In the code file, you can have the following statements:

protected void Page_Load(object sender, EventArgs e) {    Master.TitleBoxText = "Programming ASP.NET-version 2.0"; } 

The @MasterType directive supports two mutually exclusive attributes VirtualPath and TypeName. Both serve to identify the master class to use. The former does it by URL; the latter does it by type name.

Changing the Master Page Dynamically

To associate an ASP.NET content page with a master page keeping in mind that in no case can you associate a classic ASP.NET page with a master you use the MasterPageFile attribute of the @Page directive. MasterPageFile, though, is also a read/write property on the Page class that points to the name of the master page file. Can you dynamically select the master page via code and based on run-time conditions?

Using a dynamically changing master page is definitely possible in ASP.NET 2.0 and is suitable, for example, for applications that can present themselves to users through different skins. However, programmatically selecting the master page is not a task that you can accomplish at any time. To be precise, you can set the MasterPageFile property only during the PreInit page event that is, before the runtime begins working on the request:

protected void Page_PreInit(object sender, EventArgs e) {     MasterPageFile = "simple2.master"; } 

If you try to set the MasterPageFile property in Init or Load event handlers, an exception is raised.

Note 

The Master property represents the current instance of the master page object, is a read-only property, and can't be set programmatically. The Master property is set by the runtime after loading the content of the file referenced by the MasterPageFile property.

 


Programming Microsoft ASP. Net 2.0 Core Reference
Programming Microsoft ASP.NET 2.0 Core Reference
ISBN: 0735621764
EAN: 2147483647
Year: 2004
Pages: 112
Authors: Dino Esposito
BUY ON AMAZON

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net