I am thinking about the asp.net 2.0 code behind model.
After I drag a button onto my Default.aspx page, I got the following declaration in my Default.aspx.designer.cs file:
public partial class _Default {
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
protected global::System.Web.UI.WebControls.Button Button1;
}
And now it's OK for me to write the following code in Default.aspx.cs file:
protected void Button1_Click(object sender, EventArgs e)
{
Button1.Text = "clicked!";
}
But I am wondering, what I got is nothing but a declaration of Button1 variable of Button type, it hasn't been instanciated, how could this code run without trigging a Null Reference Exception?
I think there must exist some code like this somewhere:
Button1 = new Button();
But where is this code? When is this code executed? Who executes it?
Many thanks...
Update - 1 - 21:17 12/15/2010
I found 2 auto-generated file in a mysterious location C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\edd9f4a1\7f113408, they are:
App_Web_x_swwj6s.1.cs
App_Web_x_swwj6s.0.cs
I found code like below in the App_Web_x_swwj6s.0.cs file:
private global::System.Web.UI.WebControls.Button @__BuildControlButton1()
{
global::System.Web.UI.WebControls.Button @__ctrl;
@__ctrl = new global::System.Web.UI.WebControls.Button();
//....
this.Button1 = @__ctrl;
return @__ctrl;
}
And this method is invoked in the below code:
private global::System.Web.UI.HtmlControls.HtmlForm @__BuildControlform1()
{
//....
global::System.Web.UI.WebControls.Button @__ctrl1;
@__ctrl1 = this.@__BuildControlButton1();
//......
}
And finally the above code is invoked in the following method:
protected override void FrameworkInitialize()
So I believed that the FrameworkInitialize() method is the one who did the dirty job of bind the control reference to a control instance.
To prove this, I intentionally wrote the following code in my code-behind file:
protected override void FrameworkInitialize()
{
this.Button1 = null;
}
I hope there would be a Null Reference Exception when I click the button, but strange enough, the whole web site run smoothly.
Is it true that all the controls I declared in the aspx file are created with the FrameworkInitialize() method? Why there's no Null Reference Exception in the above scenario?
Many thanks again.
Update - 2 - 21:43 12/15/2010
I think I may find the explanation, I checked the final page class generated by ASP.NET with .NET reflector. Its deriving relation is like this:
default_aspx class (The ultimate class representing the page)<--- _Default class (the code behind class) <--- System.Web.UI.Page
And in the default_aspx class, I found this:
protected override void FrameworkInitialize()
{
base.FrameworkInitialize(); // Button1=null is executed here.
this.__BuildControlTree(this); // Here Button1 is STILL set to an instance.
base.AddWrappedFileDependencies(__fileDependencies);
base.Request.ValidateInput();
}
So, this could explain why my intention to set the Button1 to null failed.
Now, my question is, does the FrameworkInitialize() method has to be called at the very beginning of a page's life cycle so that we could use the control on the page afterwards.
Update - 3 - 3:45 PM 12/16/2010
From here:
Once the HTTP page handler class is fully identified, the ASP.NET run time calls the handler's ProcessRequest method to process the request. Normally, there is no need to change the implementation of the method as it is provided by the Page class.
This implementation begins by calling the method FrameworkInitialize, which builds the controls tree for the page. The method is a protected and virtual member of the TemplateControl class—the class from which Page itself derives. Any dynamically generated handler for an .aspx resource overrides FrameworkInitialize. In this method, the whole control tree for the page is built.