Search code examples
asp.netmaster-pagescontentplaceholder

Use ContentPlaceHolder's default content instead of page's content


When a page that uses a master page doesn't have an asp:Content control for one of the master page's ContentPlaceHolders, the default content is shown instead. I want to use that default content on a page that does have an asp:Content control for that ContentPlaceHolder.

In the page that uses the master page I want to decide in code whether to use the default content or the page-specific content. How can I show the default content from the master page instead of the content from the asp:Content control for the ContentPlaceHolderID?

For instance, say I have a ContentPlaceHolder for a menu. The default content shows a basic menu. The page builds the menu from a query, but if there's no result for the query I want to show the default menu. By default though, the empty asp:Content control will be shown. How do I get the master page's default content instead?


Solution

  • The best approach I've come up with is not to use default content in the ContentPlaceHolder. Instead, I added the default content in a PlaceHolder adjacent to the ContentPlaceHolder:

    <asp:ContentPlaceHolder ID="Menu" runat="server" /><!-- no default content -->
    <asp:PlaceHolder runat=server ID="DefaultContentForMenu" Visible=false
        EnableViewState=false >Default menu content here</asp:PlaceHolder>
    

    Then I added a ForceDefaultContentForMenu property to the master page so that pages that use the master page can specify that the default content should be used even if the page provides its own content.

    The master page's Render method shows the default content if the ForceDefaultContentForMenu property is true or the content placeholder is empty:

    protected override void Render(HtmlTextWriter writer)
    {
        if (ForceDefaultContentForMenu || !Menu.HasControls())
        {
            Menu.Controls.Clear();
            DefaultContentForMenu.Visible = true;
        }
        base.Render(writer);
    }
    

    Now pages that use the master page will get the default content by default if they don't add their own content for the Menu content placeholder, but can specify that the default content should be used instead of their own content.

    The only drawback I've found with this approach is that when Visual Studio adds the content area to a page the default content isn't copied. For the work I'm doing this is a benefit rather than a drawback, since if I'm adding the content area to a page it's because I don't want the default content.