Monday, January 22, 2007

Referencing a Master Page from a User Control

UPDATE: It turns out this works fine for debugging, but once you go to publish it doesn't work at all (if you check the Allow Updateable box). It looks like the Reference Directive is being ignored when compiling the code behind file so it can't find the class "ASP.nameofmymasterpage_master". I'll update again if I find a solution. Very discouraging.

UPDATE 2: see workarounds below

I ran into a situation where I needed to access a custom property of a master page from within a user control. Were I dealing with a regular page, the MasterType directive would have worked fine, but this doesn't work for user controls.

I started by figuring out the name of the type of my custom master page by mousing over a line like "Page.Master" in one of my aspxs that contained a MasterType directive. This told me that the type of the master page is something like "ASP.nameofmymasterpage_master". The parent class for this is the class in the master page cs file, usually something like "nameofmymasterpage".

I then tried casting "Page.Master" to "ASP.nameofmymasterpage_master" in the cs file for my user control, but the compiler complained that it didn't know about this type. To make it aware, you have add the seldom used Reference directive to the ascx file. Something like "<%@ Reference VirtualPath="~/nameofmymasterpage.master" %>". Then the type "ASP.nameofmymasterpage_master" is available so the line with the cast can compile and everything works.

In summary, put this in the ascx:
<%@ Reference VirtualPath="~/nameofmymasterpage.master" %>

So that you can do this in the ascx.cs:
string thingIwant = (Page.Master as ASP.nameofmymasterpage_master).CustomProperty;

WORKAROUNDS:
1. Just use Web Application Projects which I should be doing anyway, but I haven't yet gotten the time to update all the sites we currently have
2. Define an interface in your App_Code folder with all the operations you need exposed from your master page. In your master page cs file, mark the class as implementing your interface. Then in your ascx, just cast Page.Master to your interface type and go to town. You don't need the Reference directive at all. Not as simple as it should be, but it works.

Tuesday, January 16, 2007

Type Theory

For fun I just finished reading Pierce's Types and Programming Languages. I missed some of the formal background for PL while in school since I skipped a pre-req or two to get into a compiler class that my favorite professor was teaching. It was nice to go back and fill in the gaps. TAPL came highly recommended from LtU and it didn't disappoint. Now, of course, I'm seeing new programming languages as the answer to everything.

More specifically I'm interested in the practical difference between a statically structurally typed language with type inference and a dynamically typed language. It seems that structural typing gets pretty close (depending on the implementation) to the duck typing promised by languages like Ruby while still being checked at compile time. Obviously there are some compromises like meta-programming, but there are even some statically typed languages that offer this as well.

Unfortunately there isn't a good candidate .net language to play with. Although OCaml is structurally typed, F# remains nominally typed, probably for .net interop reasons. Because of the nature of the CLR, any structurally typed language would have to in effect fake it, via reflection or something. I'm thinking of writing a toy language just to play with this, exposing parameters as "object", invoking methods via reflection, and maybe indicating type constraints via an attribute or something. Hopefully I'll find some time for this.

Also, this is quite good (and released under a Creative Commons license), despite the Boring Manager's name.