Thursday, July 12, 2007

ASP.NET Pages offer us a declarative way to set some of the properties such as Theme, MasterPageFile or Title in the Page directive. A nice feature indeed. The problem is that the same ASP.NET or maybe the Web Forms framework and Visual Studio stand in our way when we try to set our custom properties this way. It is possible but not developer friendly in a least.

To do it, we have to use the CodeFileBaseClass property and set it to the same base class that our page inherits from. More on this on K. Scott Allen's blog. Although it is technically possible to set this attribute to some class upper in the hierarchy I have encountered random weird behavior of Visual Studio after doing so. To be safe it is better to use the same base class both in the inheritance and in the CodeFileBaseClass attribute.

What about generic types? The tool (Visual Studio) support for generic types has never been great (not to say there is virtually no support). The fact that Visual Studio makes it hard to use CodeFileBaseClass difficult does not make it easier when it comes to generic base pages, but it can be done!

Suppose we have a type in the App_Code directory:

public class MyType
{
}
And also, defined in the same directory, we have a base page class:
public abstract class BasePage<T> : Page
{
}

And finally there is a Default.aspx page in the project that inherits from the our BasePage class:

public partial class _Default : BasePage<MyType>
{
}

Obviously we cannot just put a type name as BasePage:

CodeFileBaseClass="BasePage"

It won't work, because there is no such type. The message is: "Could not load type 'BasePage'". Our type is generic so we have to use it's full name:

CodeFileBaseClass="BasePage<MyType>"

But this also won't work. It will fail with the same message. That's becuse it is a C# specific representation of a generic type name. What CLR sees is something different. In order to make it work with a generic class we have to lower ourselves to the CLR level and use it's notation. This would mean using something like:

CodeFileBaseClass="BasePage`1[[MyTypebecause]]"

This thing actually works! If your types reside in some kind of namespace, has many generic parameters or worse yet, is part of a strongly named assembly, the whole CodeFileBaseClass starts to look scary and I don't think it is worth it. There is a trick however that may civilize the thing you enter in CodeFileBaseClass that allows to use any kind of base page class without making it complex. Just create an intermediate class like this:

public class StandardBasePage : BasePage<MyType>
{
}

and inherit your page from it. Than you can use this new type's name in CodeFileBaseClass without having to deal with generic parameter issues.

kick it on DotNetKicks.com