【发布时间】:2010-12-14 15:53:36
【问题描述】:
我正在考虑模型背后的 asp.net 2.0 代码。
在我将一个按钮拖到我的 Default.aspx 页面后,我在我的 Default.aspx.designer.cs 文件中得到了以下声明:
public partial class _Default {
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
protected global::System.Web.UI.WebControls.Button Button1;
}
现在我可以在 Default.aspx.cs 文件中编写以下代码:
protected void Button1_Click(object sender, EventArgs e)
{
Button1.Text = "clicked!";
}
但我想知道,我得到的只是一个Button类型的Button1变量的声明,它还没有被实例化,没有这个代码怎么能运行触发空引用异常?
我认为某处一定存在这样的代码:
Button1 = new Button();
但是这段代码在哪里?这段代码什么时候执行?谁来执行?
非常感谢...
更新 - 1 - 21:17 12/15/2010
我在一个神秘的位置发现了 2 个自动生成的文件 C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\edd9f4a1\7f113408,它们是:
App_Web_x_swwj6s.1.cs
App_Web_x_swwj6s.0.cs
我在 App_Web_x_swwj6s.0.cs 文件中找到如下代码:
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;
}
并且这个方法在下面的代码中被调用:
private global::System.Web.UI.HtmlControls.HtmlForm @__BuildControlform1()
{
//....
global::System.Web.UI.WebControls.Button @__ctrl1;
@__ctrl1 = this.@__BuildControlButton1();
//......
}
最后通过下面的方法调用上面的代码:
protected override void FrameworkInitialize()
所以我相信 FrameworkInitialize() 方法是将控件 reference 绑定到控件 instance 的脏活.
为了证明这一点,我特意在我的代码隐藏文件中编写了以下代码:
protected override void FrameworkInitialize()
{
this.Button1 = null;
}
我希望当我点击按钮的时候会有一个空引用异常,但奇怪的是,整个网站运行顺利。
难道我在aspx文件中声明的所有控件都是用FrameworkInitialize()方法创建的吗?为什么上面的场景没有空引用异常?
再次感谢。
更新 - 2 - 21:43 12/15/2010
我想我可能会找到解释,我检查了 ASP.NET 使用 .NET 反射器生成的最终页面类。它的推导关系是这样的:
default_aspx 类(代表页面的终极类)_Default 类(类背后的代码)
在 default_aspx 类中,我发现了这个:
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();
}
所以,这可以解释为什么我打算将 Button1 设置为 null 失败。
现在,我的问题是,是否必须在页面生命周期的最开始调用 FrameworkInitialize() 方法,以便之后我们可以在页面上使用控件。
更新 - 3 - 2010 年 12 月 16 日下午 3:45
来自here:
一旦 HTTP 页面处理程序类 完全确定,ASP.NET 运行时 调用处理程序的 ProcessRequest 处理请求的方法。 正常情况下不需要更改 方法的实现 由 Page 类提供。
这个实现首先调用 方法 FrameworkInitialize,它 为页面构建控件树。 该方法是受保护的和虚拟的 模板控件的成员 类——Page 本身所在的类 导出。任何动态生成的 .aspx 资源的处理程序 覆盖 FrameworkInitialize。在这个 方法,整个控制树为 页面已构建。
为您宝贵的 cmets 开始赏金。 :)
【问题讨论】:
-
由于“答案”已被删除,但我认为其中的链接可能仍有与查看此问题的人相关的信息:peterkellner.net/2006/07/12/…
标签: asp.net code-behind