3

我一直在使用默认的 ASP.NET Web 应用程序模板,以下代码引发异常:

你调用的对象是空的。

单击创建的按钮时。

谁能提供技术解释?

注意 1:标记只是一个带有占位符的空白页面 - 见下文。

注意2:替换ButtonLinkButton,代码不会抛出异常并且可以正常工作。

public partial class test : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        foo();
    }
    protected override void OnLoad(EventArgs e)
    {
        foo();
    }
    protected void foo()
    {
        placeholder1.Controls.Clear();
        placeholder1.Controls.Add(new Button() { Text = "test", ID = "btn" });
    }
}

标记:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test.aspx.cs" Inherits="WebApplication1.test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:PlaceHolder runat="server" ID="placeholder1" />
    </div>
    </form>
</body>
</html>
4

3 回答 3

0

我的猜测是,一旦从回发中返回,该按钮就为空。您实际上是在删除 Button 并创建一个可能会删除关联事件的新按钮。

只是为了支持我的理论,我尝试了这个:

protected override void OnInit(EventArgs e)
{
    if (!IsPostBack)
        foo();
}
protected override void OnLoad(EventArgs e)
{
    if (!IsPostBack)
        foo();
}
protected void foo()
{
    placeholder1.Controls.Clear();
    placeholder1.Controls.Add(new Button() { Text = "test", ID = "btn" });
}

并且没有收到您收到的错误。

你为什么要像你一样在运行时添加按钮?

于 2011-03-24T15:02:40.777 回答
0

看起来 placeholder1 或 placeholder1.Controls 为空。这是给定您的代码示例的 NullReferenceException 的唯一解释。

于 2011-03-24T14:47:45.000 回答
0

如果您从 OnLoad() 中删除对 foo() 的调用,我认为代码将开始工作。

其原因在于页面生命周期中的事件顺序。为了使控件能够引发事件,需要在 ProcessPostData()、RaiseChangedEvents() 和 RaisePostBackEvents() 事件发生之前创建控件(参见http://www.eggheadcafe.com/articles/o_aspNet_Page_LifeCycle.jpg用于页面生命周期的图形表示)这些事件在 OnInit() 之后但在 OnLoad() 之前引发

由于您的代码目前通过在 OnLoad() 中调用 foo(),您会破坏在 OnInit() 中调用 foo() 时创建的实例,因此当引发事件时,引发它的控件不再存在,因此“对象引用未设置为实例”消息。

于 2011-05-28T13:11:18.887 回答