Practical ASP.NET

Integrating Master Pages and Content Pages

Not content with providing a solution for displaying information from the Content page on its MasterPage, Peter returns to the topic to solve the problem from another direction.

In an earlier column ("Integrating Master Pages + Content Pages + a Little AJAX") I showed one way to display in a MasterPage information from the Content page it was displaying. The problem is relatively common: There is some information that you want to display in the same place on every page (and, as a result, you want to put it on the MasterPage) but the information you want to display is being provided by the Content page.

In that column, I added a property to the MasterPage and accessed it from the Content page using the Page object's Master property. This makes sense if you regard Content page as controlling the operation since it's providing the information and think of the MasterPage as the child of the Content page (not an unreasonable point of view, provided you don't take the "Master" in MasterPage too seriously).

MasterPage in Control
However, you could make a case that the MasterPage should be responsible for its own content and, as a result, the MasterPage should be controlling the process. From that point of view, if you wanted to update a Label on the MasterPage with the title of its Content page, you would use code in the MasterPage. This code, put in the MasterPage's Init, Load or PreRender events, would do the trick:

Me.PageTitleLabel.Text = Page.Title

This solution also means that you have to add code in only one place -- the MasterPage -- instead of having to update every Content page.

Unfortunately, this tactic works only as long as the information you want from the Content page is available from a property on the Page object. However, if the Content page is generating the information to be displayed in the MasterPage, then you'll need to add some code to the Content page. For instance, if you wanted to display the user's name and the page's Title, you could add a property like this to the Content page:

Public ReadOnly Property NameAndTitle() As String
  Get
    Return User.Identity.Name & ": " & Page.Title
  End Get
End Property

Accessing this custom property from the MasterPage is more complicated than accessing on the Page's property because, of course, my NameAndTitle property won't appear on the Page object. To access my custom property, I have to cast the Page object to the type of the Content page. It's not reasonable to cast to every different Content page type but there are at least two ways to avoid doing that:

  • Create a base class that inherits from Page and have all of the Content pages on the site inherit from that class instead of from the default Page class.

  • Create an interface that defines the property and have the Content page implement it.

If the property appears on all pages and the code in the property is usually the same in every page, the first option is probably the best way to go (if the code in the property does vary from one page to another, you can make the property override-able and replace it with page-specific code, as necessary). If, on the other hand, only some of your pages will need this property or the implementation is different on every page, the second option is probably your best choice.

Adding an Interface
If you do decide to use the Interface in a Web site (as opposed to a Web Project), you'll need to add a class file to the App_Code folder and then replace the default code with an Interface declaration. For some reason, the Add New Item dialog for Web sites doesn't include Interface files. Regardless of how you get there, an Interface that includes my property would look like this:

Public Interface IPHV

    Property ReadOnly NameAndTitle() As String

End Interface

To implement the interface in a Content page, I would use code like this to implement the interface and add code to it:

Partial Class CustomerOrders
    Inherits System.Web.UI.Page
    Implements IPHV

Public ReadOnly Property NameAndTitle() As String _ 
                  Implements IPHV
  Get
    Return User.Identity.Name & ": " & Page.Title
  End Get
End Property

Now, in the MasterPage's Load event, I can check to see if a page has implemented my interface and (if it has) access the property, as this code does:

If TypeOf Page Is IPHV Then
            Me.PageTitleLabel.Text = CType(Page, IPHV).TitleAndName
End If

So now you have two ways to integrate your MasterPage and Content page: Add properties to your MasterPage that you access from your Content page or add properties to your Content page and access them from your MasterPage. Your choice.

And thanks to Doug Rehnstrom who's been bugging me about this for years.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events