Extending Master Pages

Note: this entry has moved.

During last March I was writing a chapter for a soon to be released Wrox Professional book on Advanced ASP.NET. As you may already know, Wrox is gone by now, so my chapter (and the whole book) never made it to the public L

 

During that time (late-night time…) I wrote an entire chapter about Page Templates/Visual Inheritance/YourFavoriteNameGoesHere in ASP.NET. I ended up with a 50 pages chapter with more of its content dedicated exclusively to the Master Pages technique (coded by Microsoft’s David Ebbo) and how to extend it.

 

Although Master Pages was just a quick sample that David put together to demo a basic concept, it is, in my opinion, the best way to go if you’re looking to implement page templates in your ASP.NET application. But, as with any quickly put together sample, it leaves some room for improvement and fixes. I will summarize a couple of them here hoping that if you’re actually using Master Pages or considering using it you could benefit by knowing about them.

 

NOTE: if you’re not familiar enough with Master Pages or any other template technique, I recommend you to take a look at fellow MVP Paul Wilson’s articles on the subject before continuing this reading.

 

You’re already familiar? Ok then… read on J

 

Better integration with the ASP.NET parser

 

This means moving some code from Control.AddParsedSubObject to a ControlBuilder for executing code only once at parsing time. There is also room for adding a couple of new checking’s (i.e. enforcing attributes to be set).

 

Couple of fixes

 

Let’s take a look at the following fragment for ContentContainer.OnInit:

 

protected override void OnInit(EventArgs e) {

   if (MasterPageFile == null)

      throw new Exception("You need to set the MasterPageFile property");

 

   // Load the master page

   Control masterPage = Page.LoadControl(MasterPageFile);

 

   foreach (Content content in _contents) {

      // Look for a region with the same ID as the content control

      Control region = masterPage.FindControl(content.ID);

      if (region == null) {

           throw new Exception("Could not find matching region for content with ID '" + content.ID + "'");

      }

.

.

.

}

 

There are two main pitfalls (marked in bold) to watch out for in the above code:

 

1.        As you already know the Control.FindControl method when called with a simply ID will search into the current naming container for the specified control; this will break when your Region controls are contained in a different naming container than the usercontrol itself, i.e:

<owc:Region runat=”server” id=”one” />

<owc:MyOwnNamingContainer runat=”server”>

     <owc:Region runat=”server” id=”two” />

</owc:MyOwnNamingContainer runat=”server”>

<owc:Region runat=”server” id=”three” />

 

2.        Checking against region == null it’s not enough to guarantee correct usage of Master Pages. For example it could happen that a page developer while creating a new page specified a Content control with an ID that has no correspondent Region control but matches some other control type; needless to say the check won’t fail and we’ll be in trouble. So we should be checking region against null plus that it is an instance of a Region type.

 

Support for inheritance between templates

 

This is by far the most powerful feature I’ve added to Master Pages. There is some real power (code reuse, simplified maintenance, etc) you could benefit from when being able to inherit between templates. The code to add this feature is quite straightforward, basically a modified ContentContainer that is aware of inheritance and a couple of support methods to walk the inheritance chain and setup Region controls appropriately.

 

Master Pages as an application-level feature

 

Coding a config section for Master Pages that you could use to easily setup it for your particular web application is definitively useful. With settable attributes like BaseUrl that would allow you to easily change the location where to look for templates.

 

VS.NET integration

 

Due to the fact that the page parser is currently not extensible, it is required that you manually add some repetitive declarations to any page that uses templates and also to your templates files. This tends to be a really boring and repetitive (did I already mentioned that?) task. I’ve tackled this by coding a couple of VS.NET wizards and templates (VS.NET templates this time!) that create the necessary skeleton code thus saving you from boring and rep… typing.

 

Other features I’ve coded are support for: I18N, design-time, programmatically handling Master Pages and something else I can’t remember right now J… I could address these features in a future post if there is enough interest in them.

 

7 Comments

  • Hi, I like your ideas about that very cool sample Masterpages. I always wonder how you can achieve so much with so few lines of code ;-)





    I would be very interested in your extensions. I already extended Masterpages to have some kind of Designer Support. I am thinking about Caching and extending the Masterpages to include repeatable Regions (for Tables of controls) with Template for Header, Item and Footer. What do you think?





    Marius Filipowski


    ITERGO

  • The extensions sound interesting. Can we peek at the source?

  • Could you give some details on how to add inheritance to masterpages? That alone would save me from duplicating templates files. Thanks in advance for any additional info.

  • Is there any possibility that you could share your code for the MasterPages? I would like to see what you have done with it and see if I can adapt any of it to my app.

  • Master Pages needs it's own open source movement until MS releases their version. How can we use your code as the starting point?

  • Victor -



    Some how, I managed to come across this code at some point in the past few months, but am not sure where. I am working with this in .NET 1.0, and it seems to be working effectively enough thus far, but I am looking to add some design time support to the &quot;MasterPage.&quot; I have 2 files that I am pulling into &quot;content&quot; areas and would like to be able to show things the default pages at design time. Any ideas?

  • I have been using the master pages for a while now and love it. Can you share your code?

    thx

    dave

Comments have been disabled for this content.