Visual Inheritance with Master Pages and the @Reference tag
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="https://weblog.west-wind.com/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
- Adding minimal OWIN Identity Authentication to an Existing ASP.NET MVC Application
- Resolving Paths To Server Relative Paths in .NET Code
- Map Physical Paths with an HttpContext.MapPath() Extension Method in ASP.NET
- Back to Basics: Rewriting a URL in ASP.NET Core
- Getting the Client IP Address in ASP.NET Core
The Voices of Reason
# re: Visual Inheritance with Master Pages and the @Reference tag
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.
# re: Visual Inheritance with Master Pages and the @Reference tag
"Cannot find ContentPlaceHolder 'cphBody' in the master page 'MasterPage/ncvr.master', verify content control's ContentPlaceHolderID attribute in the content page"
Any ideas
# re: Visual Inheritance with Master Pages and the @Reference tag
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.