OdeToCode IC Logo

Strong Typing and Nested Master Pages

Friday, November 11, 2005

Here is a little tip for getting a strongly typed Master property when using nested master pages in ASP.NET 2.0.

Let’s say you start with the following, top level master page:

<%@ Master Language="C#" %>

 

<script runat="server">

 

    public string BigFooterText

    {

        get { return BigFooter.Text; }

        set { BigFooter.Text = value; }

    }

 

</script>

 

<html>

<head runat="server"/>

 

<body>

    <form id="form1" runat="server">

    <div>

        <asp:contentplaceholder id="BigContent" runat="server"/>

        <asp:Label ID="BigFooter" runat="server"/>

    </div>

    </form>

</body>

</html>

A second, nested master page provides the content for the top level master.

<%@ Master Language="C#" MasterPageFile="~/BigMaster.master"  %>

<%@ MasterType VirtualPath="~/BigMaster.master" %>

 

<script runat="server">

 

    public string LittleFooterText

    {

        get { return LittleFooter.Text; }

        set { LittleFooter.Text = value; }

    }

 

</script>

 

<asp:Content ContentPlaceHolderID="BigContent" runat="server">

 

  <asp:ContentPlaceHolder ID="LittleContent" runat="server"/>

  <asp:Label ID="LittleFooter" runat="server"/>

 

</asp:Content>

Now finally, an ASPX content page using the nested master as it’s master page. Notice the web form can reach the BigFooterText property of the top level master page without casting.

<%@ Page Language="C#" MasterPageFile="~/LittleMaster.master" Title="Untitled Page" %>

<%@ MasterType VirtualPath="~/LittleMaster.master" %>

<%@ Reference VirtualPath="~/BigMaster.master" %>

 

<script runat="server">

    protected void Page_Load(object sender, EventArgs e)

    {

        Master.LittleFooterText = "hello";

        Master.Master.BigFooterText = "world";

    }

</script>

 

<asp:Content ID="Content1" ContentPlaceHolderID="LittleContent" Runat="Server">

This is some content

</asp:Content>

Comments:

Typically, the Master property of a form is of type MasterPage. The @ MasterType directive instructs ASP.NET to generate the code for a strongly typed MasterPage property, and to ensure the assembly is properly referenced in scenarios where the master page and the content page end up in different assemblies. The web form needs both an @ MasterType directive (for the nested master) and an @ Reference directive (to the top level master page) for the compiler to see both types.

This setup feels fragile to me. I think a better approach would be to remove the @Reference directive from the aspx file, and add a public member to the nested master page that can forward data to the top level master. This approach reduces coupling and results in less breakage when the inevitable round of changes come to the top level master.