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.
Other Posts you might also like