ASP.NET Whidbey Partial Types and Events

In the brave new world of ASP.NET 2.0 AKA Whidbey the seperation between markup and code has changed. In ASP.NET 1.x the developer typically created a code-behind page (C#, VB.NET) and an ASP.NET mark-up page (.aspx) that inherited from it. Control declarations (and event handlers in C#) where declared and wired up in a region of the code-behind file that VS.NET kept “in synch” (well…tried to keep in synch) with your .aspx markup page. The new way uses partial types (new compiler features in VB.NET /C#) *. When your page is compiled (either pre-compiled or first viewed) the ASP.NET runtime creates a partial type that contains the variable declarations for your page (and any inline <% %> style code you have too). If you have specified a partial type with your page (via the CompileWith @Page directive) then this file and the partial type that ASP.NET created are munged into a single class (well, that is how I understand it all to be taking place anyway ).

An interesting question I wondered was, how do my event handlers get wired up? In VS 2005 event handlers for VB.NET did not have any “Handles” directive after them, and C# does not have the option to wire up it’s event handlers this way, so how was it being done? The answer lies in one of the stranger @Page directives in ASP.NET - the AutoEventWireUp directive. VS.NET 20023 always set this to false by default, and you could see some weird “event handlers being called twice“ behavior if you unintentionally removed it but kept your event hander wire up code. It seems that ASP.NET 2.0 uses them by default instead of using “Handles“ or attaching event handlers elsewhere. I never really understood the purpose of the AutoEventWireUp directive to begin with. You could possibly make a case for it being a “convenience“ feature, so please leave a comment if you know why it exists.

* Note: I keep reading from time to time that partial types are a CLR feature. I’m pretty sure partial types are a compiler feature, but I keep hearing the “CLR feature” story from so many places that I have begun do doubt my correctness on this one.

All this is, of course to the best of my very incomplete knowledge while examining the workings of a pre-beta product. YMMV, contents may have shifted during transport, actual colour may differ from those shown etc.. etc..

Comments

Aydsman
It’s my understanding that the "AutoEventWireUp" when set to true looks for methods named a certain way to "wire up" the events.

For example, I have a WebControls.Button control called "myButton". To handle the "Click" event I would create a method:

Public Sub myButton_Click(…)

with the appropriate args. From what I’ve seen in the past to reference methods in this way they cannot be "Private" (ie must be visible to your ASPX class), however, this may be different with the partial classes stuff.

Note that VS.Net names the methods this way automatically, which is why if you set "AutoEventWireUp" to "True" and you also have the "Handles" modifier on your methods they get "wired up" twice. This is why you get double firing.

Hope I was somewhat accurate on this :)
16/06/2004 1:54:00 AM
Christian Romney
Worse yet, try to get to the partial type file and, say, inherit from a class other than System.Web.UI.Page like Acme.Web.PageController.
16/07/2004 4:45:00 AM
Ezequiel Espíndola
The answer is easier than that. I’ve just tryed some code with AutoEventWireup to false and true and nothing seems to change. Other than an overriden property added to the source code for the Default.aspx page on the Temporary ASP.NET Files folder.

If you take a look inside C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\Temporary ASP.NET Files\ after compiling, you would find a folder with the name of your website and some folders and files with strange names inside it. I don’t know what each of these means, but the partial classes are there as .cs or .vb files.

Only if you put the AutoEventWireup page code directive to false, you get this on one of the strange named .cs files:

protected override bool SupportAutoEvents {
get {
return false;
}
}

But nothing seems to change with it.

ASP.NET 2 generates a file for your .aspx page and and then compiles it togheter with your .aspx.cs class file. There is where the wiring code lies.

In VS.NET 2002 or 2003, at least when using C#, if you double clicked an asp:Button you would get the delegate handling code created for you on the VS.NET hidden region of the code behind.

There was another way to do it though, that would wire the event from the markup code to the codebe-hind event handler methods, and that was using for example, the OnClick attribute of the asp:Button.

From what I’ve played so far with VS.NET 2005, the default behavior is to use those wiring attributes. So when you do a double click on an asp:Button you get the code-behind declaration of the event handler, and instead of the hidden region with the delegate being added, you get this:

<asp:Button ID="Button1" Runat="server" Text="Button" OnClick="Button1_Click" />

The magic resides on the files that ASP.NET generates for the .aspx page. There you’ll find the code that was previously at your sight on the code-behind, in a line similar to this:

#line 38 "C:\WebSites\MyWebsite\Default.aspx"
@__ctrl.Click += new System.EventHandler(this.Button1_Click);

Now, the question is what happens if you want to wire more than one handler to the OnClick delegate? I think you should be able to do it from the code-behind as always.
19/09/2004 4:35:00 AM
Ezequiel Espíndola
Well, I have found a case where setting AutoEventWireup to false does have an impact on the behavior of the website.

It seems that Page events are magically wired up with the use of AutoEventWireup, because I haven’t found anywhere where the wiring up is written in code. It seemd all depends on using the correct method declaration like Page_PreInit(object sender, System.EventArgs e)

If anybody knows about other possibilities, please share them.

Ezequiel
19/09/2004 5:23:00 AM