Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Visual Inheritance with Master Pages and the @Reference tag


:P
On this page:

A few days ago I talked about a useful approach to store Master Pages in a template directory so they can be tied fairly easily to Theme. At the time I was working with a Web Application Projects project, so it was pretty easy to implement the MasterPage in a 'base' directory, and then create the other templates by simply referencing the original CodeBehind class using simple code like this:

 

<%@ Master Language="C#" AutoEventWireup="true"          

           Inherits="Westwind.WebStore.WebStoreMaster" %>

 

Notice there's no CodeBehind here, only an Inherits tag that points the class implemented in the base template directory. And that works great with Web Application Projects because everything compiles into a single assembly and all pages and controls can happily see each other.

 

Now I'm trying of doing the same thing with a standard Web Projects and well, I'm running up against the Reference problems I've been bitching about so much in ASP.NET 2.0. In this situation though there's a solution because although I'm loading these master pages dynamically I'll know beforehand what the names of the pages are.

 

So the scenario is this: I have two master pages which should share the same implementation. Ideally I'd want to 'just implement' the first page as a normal Master Page (.master and .cs file in the same directory) and have the second page reference the class that is implemented by the first class.

 

So in theory at least I want to do the same as above in a standard ASP.NET 2.0 project:

 

<%@ Master Language="C#" AutoEventWireup="true"          

           Inherits="Westwind.WebStore.WebStoreMaster" %>

 

The problem is that Westwind.WebStore.WebStoreMaster is not visible to the second master page because it lives in a different directory and therefore a different assembly. If you try to run this you get a compiler error telling you Westwind.WebStore.WebStoreMaster couldn't be found.

 

It took me a while to get the right way to reference the first MasterPage properly from the second one since there many permutations of the @Reference, @Register tags. In the end the right way to reference another page/control/master class is this:

 

<%@Reference VirtualPath="~/App_Templates/Standard/WebStoreMaster.master" %>

<%@Master Language="C#" AutoEventWireup="true"

          Inherits="Westwind.WebStore.WebStoreMaster" %>

 

The @Reference command with the VirtualPath allows you to point at another page/control/master and basically forces the assembly that the page lives in to be imported into the current page/control's assembly.

 

 

The other alternative would have been to move the CodeBehind file into the App_Code directory. The big problem with that approach is that ASP.NET in that situation won't automatically create control definitions for you. So you'd have to add controls manually. Given a choice then using the master Master page (intentional <g>) approach is easier to work with if you want to work in a visual/interactive environment.


The Voices of Reason


 

Marc Brooks
March 27, 2006

# re: Visual Inheritance with Master Pages and the @Reference tag

"The big problem with that approach is that ASP.NET in that situation won't automatically create control definitions for you."

I would call that a feature! That way you, and ONLY you, are in control of the "interface" that your master-base-class exposes. This is a good thing... it forces you to be explicit about the things you want two force-share. It also opens the way for testable interfaces by letting you stub out the actual UI of the master page in a test.

Rick Strahl
March 27, 2006

# re: Visual Inheritance with Master Pages and the @Reference tag

Mark, it's great if you truly want to create a generic base class and then inherit the page from that class. And I already do that with my MasterPage class which is has a generic base that for a variety of functionality.

But if you have a 'CodeBehind' class you can't get the App_Code directory to do what normally happens with stock .cs/.vb file and that is kind of a bummer.

Of course you can always create a pure base class with any controls you choose and let the partial class inherit from that to get a fixed environment but that's not what I call visual inheritance in this context.


Scott
July 25, 2006

# re: Visual Inheritance with Master Pages and the @Reference tag

I'm trying something like this using Web Application project. I inherit a masterpage from my baseclass dll just as you have. Compiles with no errors, but I
"Cannot find ContentPlaceHolder 'cphBody' in the master page 'MasterPage/ncvr.master', verify content control's ContentPlaceHolderID attribute in the content page"

Any ideas

# DotNetSlackers: Visual Inheritance with Master Pages and the @Reference tag


Rick Strahl's Web Log
October 15, 2006

# Themes and Templating Master Pages - Rick Strahl's Web Log

Themes in ASP.NET 2.0 are lacking in that they don't really support code type controls like pages or even more importantly Master Pages. Here is a simple outline that you can use to incorporated templates Master Pages alongside your Themes in a consistent way.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024