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

  • Compare New GitHub Copilot Free Plan for Visual Studio/VS Code to Paid Plans

    The free plan restricts the number of completions, chat requests and access to AI models, being suitable for occasional users and small projects.

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

Subscribe on YouTube