Welcome to MSDN Blogs Sign in | Join | Help

Creating a ControlBuilder for the page itself

One user on my previous post on ProcessGenerateCode asked how he could associate a ControlBuilder not with a control, but with the page itself.  There is in fact a way to do it, and it’s another one of those things that have never really been advertized.  The trick is that instead of associating the ControlBuilder using the standard ControlBuilderAttribute, you need to use a FileLevelControlBuilderAttribute.  Let’s walk through a little example.

First, we create a custom page type with that attribute:

[FileLevelControlBuilder(typeof(MyPageControlBuilder))]
public class MyPage : Page {
}

We could do all kind of non-default thing in the derived Page, but I’ll keep it simple.  Now let’s write the ControlBuilder for it:

// Note that it must extend FileLevelPageControlBuilder, not ControlBuilder!
public class MyPageControlBuilder : FileLevelPageControlBuilder {
    public override Type GetChildControlType(string tagName, IDictionary attribs) {
        // If it's a Label, change it into our derived Label
        Type t = base.GetChildControlType(tagName, attribs);
        if (t == typeof(Label)) {
            t = typeof(MyLabel);
        }

        return t;
    }
}

The most important thing to note here is that it extends FileLevelPageControlBuilder, not ControlBuilder.  If you extend ControlBuilder, it may seem like it works on simple pages but some things will break (e.g with master pages).

As for what we do in that class, it’s just some random thing to demonstrate that it is in fact getting called.  Here, we change the type of all Labels to a derived type which slightly modifies the output:

public class MyLabel : Label {
    public override string Text {
        set { base.Text = "[[" + value + "]]"; }
    }
}

And then of course, we need to tell our aspx page to use our base class:

<%@ Page Language="C#" Inherits="MyPage" %>

The full runnable sample is attached below.

Published Thursday, November 20, 2008 3:48 PM by davidebb
Filed under:

Attachment(s): FileLevelControlBuilder.zip

Comments

# Dew Drop - November 21, 2008 | Alvin Ashcraft's Morning Dew

# re: Creating a ControlBuilder for the page itself

I know this is just an example scenario for the file-level control builder, but in fact for this specific scenario, there isn't a need to write a control builder.

Instead one could just remap Label to MyLabel in web.config using the tag mapping feature.

Saturday, November 22, 2008 11:11 PM by Nikhil Kothari

# re: Creating a ControlBuilder for the page itself

Right, as Nikhil says tag remapping can be used to easily change a control type. This was just some random example to quickly demonstrate that the Page ControlBuilder does in fact get called.

There is no limit to what you can do in your ControlBuilder, especially once you start using ProcessGeneratedCode (see my previous post).

Sunday, November 23, 2008 11:55 AM by davidebb

# A Little Holiday Love From The ASP.NET MVC Team

A Little Holiday Love From The ASP.NET MVC Team

Friday, December 19, 2008 12:49 PM by you've been HAACKED

# re: Creating a ControlBuilder for the page itself

This is not working for me. I've configured my website (not web app) to have my base page:

[FileLevelControlBuilder(typeof(BasePageBuilder))]

   public class BasePage : Page

{}

My BasePageBuilder:

public class BasePageBuilder : FileLevelPageControlBuilder

   {

       public override Type GetChildControlType(string tagName, System.Collections.IDictionary attribs)

       {

           return base.GetChildControlType(tagName, attribs);

       }

   }

And when I put the debug on it, it does not ever hit it.

Anything I'm missing?

Monday, December 22, 2008 1:03 PM by Vi

# re: Creating a ControlBuilder for the page itself

Vi, please see the attached sample which is also using a Web Site and not a Web App.  If that one works for you, you should be able to identify what is different about your app that causes it not to work.

Monday, December 22, 2008 1:35 PM by davidebb

# re: Creating a ControlBuilder for the page itself

Well it works on the sample. But it still does not hit the debug point on the GetChildControlType override.

When does that get called because it works.

Thanks for the reply.

Monday, December 22, 2008 2:31 PM by Vi

# re: Creating a ControlBuilder for the page itself

It only gets called at the time the page gets parsed and compiled, so if it's already compiled you would indeed not hit this.  Try just resaving the aspx page and requesting it again, and you'll see that BP getting hit.

Monday, December 22, 2008 2:36 PM by davidebb

# re: Creating a ControlBuilder for the page itself

I figured out the difference. It doesn't appear to work when your page is set to use a seperate code file. (Code-Behind).

That sound right?

Monday, December 22, 2008 2:51 PM by Vi

# re: Creating a ControlBuilder for the page itself

You're right!  The good news is that it's easy to fix.  You just need to add CodeFileBaseClass="MyPage" to the @page directive of the aspx.  This is needed because the aspx parser doesn't actually know what base type your code file uses (since it can't parse the code).  So it needs that little hint.

Monday, December 22, 2008 3:26 PM by davidebb

# re: Creating a ControlBuilder for the page itself

Yup, that did it!!

Awesome, thanks!

Monday, December 22, 2008 4:16 PM by Vi

# Dynamic Data FAQ

Please post corrections/new submissions to the Dynamic Data Forum . Put FAQ Submission/Correction in

Wednesday, February 18, 2009 1:52 PM by Ricka on Dynamic Data
New Comments to this post are disabled
 
Page view tracker