14 June 2007

ASP.NET Master Pages Tips and Tricks

Take a look at how you can increase productivity and reduce maintenance with your ASP.NET 2.0 website, as Dan Wahlin shares his techniques for handling master pages.

With the release of ASP.NET 2.0, developers were given a simple and effective way to apply a consistent layout across multiple pages in a website. By creating a file with a .master extension that defined a website’s overall layout template and referencing it with the Page directive’s MasterPageFile attribute, website development and maintenance took a step forward in the direction of greater productivity.

Master pages have been around for over one and a half years, so I won’t cover the fundamentals of creating and using them, as many tutorials and books have already been written about the topic. Instead, I’ll focus on a few tips and tricks that can be applied when using master pages. To start, let’s examine how the MasterType directive can be used to reference master page controls in a strongly-typed manner from a content page.

Using the MasterType Directive

Pages that reference controls in a master page, such as a Label in the header, or Menu on the left or right of a website template, typically do so by using the Page class’s Master property along with the FindControl() method, as shown in Figure 1.

Figure 1: controls in a master page can be accessed by using the Master property combined with the FindControl() method.

While this approach certainly works, any misspellings in the quotes will not be caught by the compiler, resulting in a runtime error or a null object reference being returned. Fortunately, a strongly-typed solution is available that doesn’t involve casting the Master property to the base class of the master page in order to access its members (keep in mind that any server controls defined in the master page won’t be accessible even after a cast is performed, because they’re marked as protected by default).

In cases where a control defined in a master page needs to be exposed to one or more content pages in a strongly-typed manner, a public property with a get block can be added into the master page class as shown in Figure 2. The get block returns a Label control instance named lblHeader.

Figure 2: exposing a Label control in a master page through a public property.

A content page can reference members defined in the custom master page class by adding the MasterType directive immediately under the Page directive:

This causes the ASP.NET compiler to use the custom master page class for the type of the Page class’s Master property as opposed to the default MasterPage class located in the System.Web.UI namespace. As a result, the public property defined in the master page can be directly accessed from the content page in a strongly-typed manner, as shown in Figure 3.

Figure 3: accessing a master page’s public property from a content page by using the MasterType directive.

Using the MasterType property not only results in less code being written across multiple content pages, but also leads to better performance and eliminates the need to pass quoted values to FindControl().

Creating Master Page Base Classes

Developers who need to dynamically change master pages on the fly during the Page’s PreInit event will quickly discover that using the MasterType, along with the VirtualPath attribute, will not work. This is because the VirtualPath value is ‘hard coded’ into the content page. However, another solution exists that can be used in situations where multiple master pages are in play.

In cases where the same public property must be defined in multiple master pages (such as a Label control in a website header), a base master page class can be created that derives from MasterPage, as shown in Figure 4. This class can be added in the App_Code folder.

Figure 4: creating a custom master page file class with a single public abstract property.

By defining the BaseMasterPage class as abstract, it can’t be created directly and can only serve as the base for another class. By defining the HeaderLabel property as abstract, master pages that derive from BaseMasterPage must provide an implementation for the property. Figure 5 shows an example of deriving a master page class from BaseMasterPage and implementing the abstract HeaderLabel property.

Figure 5: deriving from BaseMasterPage and implementing an abstract property.

Pages that need to access the HeaderLabel property, but don’t want to reference a specific master page using the MasterType’s VirtualPath attribute, can use the TypeName attribute instead, as shown next:

The compiler will apply the class defined by the TypeName attribute to the Page class’s Master property allowing strongly-typed access to the HeaderLabel property from a content page, as shown earlier in Figure 3. The downside of this approach is that any custom controls defined in a concrete master page class won’t be accessible through Intellisense⢠and will have to be accessed using FindControl(). However, any master page that derives from BaseMasterPage will expose a HeaderLabel property, allowing master pages to be dynamically loaded in PreInit and used. This technique can of course be used in more advanced scenarios where multiple controls need to be exposed to content pages.

Handling Nested Master Page Design Issues

Master pages can be nested inside of other master pages in cases where an overall site’s layout template needs to contain a child template (see the sample code for an example of nesting master pages). While nesting master pages is useful in some situations, it presents a problem when trying to use the Visual Studio .NET 2005 design surface to drag and drop controls onto a content page. This problem is resolved in the next release of VS.NET (currently called Orcas).

There are a few different ways to get around the nested master page design-time issue. One potential solution is to temporarily change the MasterPageFile attribute’s value to empty strings on the Page directive. Although you won’t be able to see how the layout template defined in the master page looks when combined with the content page, you’ll be able to drag and drop controls onto the content page while in design view. However, you’ll have to remember to update the MasterPageFile attribute with the proper master page file path before moving the page to test or production environments.

Another solution is to leverage a lesser known aspect of the Page directive. Custom properties defined in an ASP.NET’s code-behind class can be referenced in the Page directive as attributes (I first learned about this trick from Microsoft’s Scott Guthrie). This feature can be used to provide a run-time reference to a master page and get around the VS.NET nested master page designer issue, as no master page is defined until the page is actually run.

Figure 6 shows a base class named BasePage that derives from System.Web.UI.Page and defines a RuntimeMasterPageFile property. BasePage overrides the Page’s PreInit event and dynamically assigns the MasterPageFile property to the value contained in the RunTimeMasterPageFile property.

Figure 6: creating a base class that derives from Page and defines a single property named RuntimeMasterPageFile. This property is used to specify the master page file that should be used at runtime.

A page that derives from BasePage can then assign the MasterPageFile attribute of the Page directive to empty strings (to avoid the designer issue mentioned earlier) but then define the master page file that should be used at runtime by adding a RuntimeMasterPageFile attribute as shown next:

Defining the RuntimeMasterPageFile attribute will cause the associated property in BasePage to be assigned a value which is then used during PreInit to assign a value to the MasterPageFile property. Although every page that references a nested master page has to derive from BasePage for this trick to work, it’s one potential solution to nested master pages that prevents having to temporarily remove the MasterPageFile attribute value to edit a content page in design view.

Sharing Master Pages across IIS Applications

The MasterPage class available in ASP.NET 2.0 derives from UserControl and just like user controls, master pages can’t be shared across IIS applications. There are a few different solutions that have been proposed, such as setting up virtual directories in each IIS application that point to the same physical folder, but there is a way to share master pages across applications with a little work on your part without resorting to duplicating virtual directories across multiple websites. By leveraging the VS.NET 2005 Publish Web Site tool it’s possible to create an assembly that contains all of the master page HTML code and C# or VB.NET code, give the assembly a strong name, and install it into the Global Assembly Cache (GAC).

I consider this trick more of a hack, but it’s something you can try out if/when the situation requires it. There are several steps involved, so a step-by-step approach follows, as well as issues to watch out for when performing the steps. I originally wrote about this some time ago on my blog at http://weblogs.asp.net/dwahlin.

  1. Create an empty Website in VS.NET 2005. Delete everything in it including App_Data, Default.aspx, and web.config (if it exists).
  2. Add a master page into the website. A simple master page file is shown in Figure 7.

Figure 7: a simple master page file that defines a ContentPlaceHolder control.

Select Build | Publish Website from the VS.NET menu. On the screen that follows, select a target location, and check all of the checkboxes shown in Figure 8. Note that the image shown in Figure 8 references a strong name key file named keyfile.snk that was created using the sn.exe command-line tool that ships with .NET. This is required in order to install assemblies into the GAC. The following syntax can be used to create the key file (run it using the Visual Studio .NET 2005 command prompt): sn.exe -k keyfile.snk.


Figure 8: using the Publish Web Site tool to create an assembly from a master page.

After the publish operation completes, open the new website in VS.NET 2005 (named MasterDemo in the example above). You should see a new assembly (with a strange name) in the Bin folder. This assembly is your master page in compiled form.Install the assembly into the GAC using gacutil.exe or drag-and-drop it into c:\Windows\Assembly using Windows Explorer. Once you’ve done this, delete the original assembly as well as the newly created XML files associated with it from the website.Add a web.config file into the website and add the following within the <system.web> begin and end tags.

You’ll need to change the name of the assembly to the name that is generated for your project (the one you added into the GAC) and change the PublicKeyToken to the one you see in the GAC. Note that the assembly attribute value shouldn’t wrap at all. I didn’t give my base master page a version for simplicity, but you can do so by applying the [assembly: AssemblyVersion(“”)] attribute to the master page code-behind class. Note that if you’re using the Web Application Project feature of VS.NET 2005 you can give your master page assembly a friendlier name. I’ll leave that as an exercise for the reader.

Add a master page into the website, but don’t create a code-behind page for it (you can, but it’s not needed in this case since the master page is only used to reference the one installed in the GAC).Remove all code within the new master page and add the following at the top. It should be the only code in the page.

If you named the original master page (the one created in step 2) differently, then you’ll need to change the Inherits value. Use the VS.NET object browser to see the name of the class within the .dll generated in step 4.

Create a content page that references MasterPage.master (the one you created in the previous step). The default ContentPlaceHolderID is ContentPlaceHolder1, so use that in the <asp:Content> tag unless you gave the id a different name in step 2.

After completing these steps, any IIS application can share the same master page used by other IIS applications by placing the empty MasterPage.master file into the application and updating the web.config file to point to the master page assembly in the GAC. The downfall of this approach is that you have to recompile the base master page and put it back into the GAC each time you need to make a change and the design time support is lacking. There may be other issues as well that haven’t been discovered yet, so perform proper testing before assuming this technique will work for your particular situation.

In working with more complex master pages you may see a ‘could not find string resource’ error come back when using this approach. If you use Reflector (http://www.aisto.com/roeder/dotnet) to analyze the code generated when the master page is compiled into the assembly, you’ll likely see a call to a method named CreateResourceBasedLiteralControl() in the code rather than seeing the actual HTML from the master page being embedded into the assembly. If you strip out some of the whitespace in the HTML it should eliminate the call to CreateResourceBasedLiteralControl() that the Publish Web Site tool added and compile correctly. For example, change the following:

To the following (all in one line):

If you try this technique and continue to get a string resource error, you’ll probably have to play around with your HTML in the base master page until no CreateResourceBasedLiteralControl() calls are made in the generated code. As mentioned before, I would advise using Reflector to take a look.


Master pages provide a great way to apply a consistent layout to an ASP.NET 2.0 website, resulting in better productivity and reduced maintenance. In this article you’ve seen various tips and tricks that can be used with master pages such as accessing master page controls in a strongly-typed manner using the MasterType directive, creating base master page classes, and working with nested master pages. You’ve also seen one potential technique for sharing master pages across IIS applications. Additional samples are available with this article’s downloadable code.

For more articles like this, sign up to the fortnightly Simple-Talk newsletter.


Tags: , , , , , ,


  • Rate
    [Total: 158    Average: 3.3/5]

Dan Wahlin (Microsoft Most Valuable Professional for ASP.NET and XML Web Services) is a .NET development instructor at Interface Technical Training (http://www.interfaceTraining.com). Dan founded the XML for ASP.NET Developers Web site (www.XMLforASP.NET), which focuses on using XML, ADO.NET and Web Services in Microsoft’s .NET platform. He’s also on the INETA Speaker's Bureau and speaks at several conferences. Dan has co-authored/authored several different books on .NET including ASP.NET 2.0 MVP Hacks and XML for ASP.NET Developers (Sams). When he’s not writing code, articles or books, Dan enjoys writing and recording music and playing golf and basketball with his wife and kids. Dan blogs at http://weblogs.asp.net/dwahlin and http://blogs.interfacett.com/dan-wahlins-blog.

View all articles by Dan Wahlin

  • Habtamu

    Great article
    I appreciate ur effort ,keep up the good work!!

  • Anonymous

    MasterType in UserControls
    So how do we get the same functionality in USerControls, I’ve tried the MasterType page directive in a UserControl and it doesn’t support that particular directive, so is there a nice clean way of getting the same functionality in UserControls?

  • Barbod

    Great article
    Really tanx , it’s so cool and great article…

  • piyush

    Please give me sample code on Remoting.
    Please give me sample code on Remoting.

  • Tom Regan

    Excellent article, thank you for posting it.

  • Ted M.

    In nearly every example for using MasterPages shows methods to access an object from the content page, as in figure 1 and 3 of this article, where the value of the label is set from within the content page. But nowhere can I find a VB example of accessing the “value” of an object in a MasterPage from the content page. For example, have a dropdownlist and a button in the MasterPage. If an item is selected in the DDL and the button is pressed, have the value of the DDL displayed in a textbox inside the content page. This cross-visibility between MasterPages and content pages would make the MasterPages even more powerful… if I knew how to do it.


  • Ben M

    Master Page name mangling
    The biggest issue I found with master pages is that the ID of the controls in the page get mangled. Instead of txtFirstName you end up with something like 0d8j_Content_txtFirstName (where content is the ID of the ContentPlaceHolder). That can obviously cause problems if you want to use CSS and JavaScript libraries that reference the IDs of elements. I found a solution where you set the ID of the master page itself in the Page_Init event. This way, I end up with IDs such as Master_Content_txtFirstName. That’s not ideal, but at least it’s consistent.

    I also found that VS.NET really doesn’t want me to put a ContentPlaceHolder within the head tag. That could be very useful for adding page specific META tags and CSS.

    I was very excited about master pages and I admit that they are very useful, but I just find them a little half baked. Go look at the Ruby on Rails implementation and you’ll see what I mean.

  • cg

    Masterpages in the GAC(gacutil.exe vs drag-and-drop)
    Using the drag-and-drop method to add assemblies to the GAC did NOT work for me. I kept getting FileNotFound exceptions when the content page was loading the assemblies.

    After spending a few hours troubleshooting, I decided to try the gacutil.exe to add the assemblies. Worked like a charm!

    Thanks Dan, very useful.

  • Sonny

    Get error
    I get the following error when I have more then 4 div tags embedded.

    An error occurred while try to load the string resources (FindResource failed with error -2147023083).

    this works fine

    <div id=”page”>
    <div id=”page-a”>
    <div id=”page-b”>
    <!– Main Page Container –>
    <!– A. HEADER –>
    <div class=”header”>


    this does not, it gives me the top error

    <div id=”page”>
    <div id=”page-a”>
    <div id=”page-b”>
    <!– Main Page Container –>
    <!– A. HEADER –>
    <div class=”header”>
    <div class=”header-top”>

    Any thoughts?

  • Daniel M

    MasterType in UserControls
    Actually I have the same question like in the second comment. Please tell us if there is a way to access exposed properties from the MasterPage in a UserControl?
    Thank you!

  • satish

    regarding master pages
    Hello sir i am satish i ahve some problem regarding master pages, please send me using masterpager demo website ….

  • RLM

    This article
    Excellent article, thanks for taking the time to explain in intermediate-advanced language so as not to waste time

    Orlando, FL

  • Carlos Cysneiros

    Not Using the GAC
    Can I use the assemblie without having to put it in the GAC. I would like for individual applications to consume the a Web Application Project .dll Can I reference it in the MasterPage itself or do I have to put it on the Web.config file?

  • Anonymous

    Master Page access from UserControl
    So I’ll be the 3rd guy to ask this question. If you don’t know, just say “I don’t know”.

  • Ravikiran

    About article
    This article is quite informative for me thank you..

  • Deepak

    Master Page access from UserControl
    Ok this is 4th guy looking for the answer !

  • Matthew Sannes

    FindResource failed with error -2147023083
    For anybody else that is having this problem, if you install SP1 for the .NET 2.0 framework, exception goes away. Hope this helps some people out.

  • Sachin

    Setting Master Page Property Of Child master page Dynamically
    how to set Master Page Property Of Child master page Dynamically in nested master page.

  • Anonymous

    invoke methos on contents from master page
    How to invoke a method in a page(content) from a button that is in the master.

  • Randy Morter

    Thanks for the help!
    Your tip on adding the MasterType directive solved a big problem for me. Thanks!

  • Nilesh India

    Really Greate Article !
    I read all the article before comming to this article. It is really Excellant and Very Practical.

  • Archna

    Sharing Master Pages across IIS Applications – Content unclear
    In point 6- which assembly will be deleted? The original version or the published version?
    In point 7- Where do we add the web.config file? Orginal version or published version?

  • Anubhuti

    Getting System.ArgumentException.
    The debugger takes me to autogenerated code

    Protected Overrides Sub FrameworkInitialize()
    End Sub

    And Get above error in line
    ‘Value does not fall within the expected range’.
    I am doing exactly same steps as above

  • swingman

    used actual dll insead of gac
    First of all i used asp:literal to solve the CreateResourceBasedLiteralControl() problem.

    Right now my current setup is having to share the dll created at the root of the applications.

    By that i can just share the same root on sourcesafe instead of people installing it at the gac. Our devs can now add the reference and change the inheritance from System.Web.UI.MasterPage to ASP.masterpage_master at the codebehind of the blank masterpage.

    So as you can see I didnt remove the code behind of the blank masterpage as the post suggests. which brings me to my quiestion.

    Based on my setup, is there a more effecient way to add the blank masterpage without having the code behind and change the inheritance?

    maybe just a .cs file or is there a way to inherit straight from the .Master file w/o the code behind files?

  • agunghario

    where’s vb code ?
    may i can get on vb.net code ?

  • BPrashanthSimple

    Try a converted
    There are bunch of online converters that can help you convert VB.net to C# and vice-versa


  • BPrashanthSimple

    Try a Converted
    Sorry abt the typo

    <a href=”http://adarshsoft.com”>Adarsh</a>

  • candyford

    ASP.NET Master Pages Tips and Tricks
    Hi Don,
    In Asp.net 2.o, Master pages are the main new controls plays an important role while comparing to Asp.net 1.0.Master pages are very useful and used in each and every website very frequently. Thanks for chosing this topic and your solution is also very good. Thanks again for sharing such an useful info with us.


  • dotnetuser

    Cast error when using technique outlined in ‘Using the MasterType Directive’
    I’ve tried the technique outlined in ‘Using the MaterType Directive’ in my project but am getting the following error:
    ‘Unable to cast object of type ‘ASP.NameOfMasterPage’ to type ‘NamespaceOfWebsite’

    This error occurs when I try to open the Content page i.e. the page doesn’t open

    The following is what I have done in my project:

    In the code behind of the parent Master page:
    public HtmlGenericControl BodyTag
    return bdMasterPageBodyTag;
    bdMasterPageBodyTag = value;

    Under the page directive in the Content page:
    <%–<%@ MasterType VirtualPath=”~/Site.Master” %>–%>

    I declare a class variable in the Content page code behind:
    HtmlGenericControl bdMasterPageBodyTag;

    In the Page_Load event of the Content page I initialise that class variable like so:
    bdMasterPageBodyTag = this.Master.BodyTag;

    I haven’t added anything to the nested Master page.

    Can someone see what I have done wrong?

    Thanks in advance

  • Khushi

    Im getting nullreference exception
    Hi Thanks for the article. I have followed the techinques mentioned here. I have used a strongly-typed solution (from fig 2 to 5).
    I’m getting null reference exception. Please guide.

    This is the code where i’m getting exception

    public partial class _Default : Page
    protected void Page_Load(object sender, EventArgs e)
    if (Convert.ToString(Session["AdminName"]) != "")

    this.Master.HeaderLabel.Text = "Welcome " + Convert.ToString(Session["AdminName"]);
    this.Master.HeaderLabel.Text = "Welcome Guest";