2011-03-24 149 views
3

我一直用默認的ASP.NET Web應用程序模板玩弄和下面的代碼會拋出一個異常:未設置的一個實例 ASP.NET/C#混亂

對象引用目的。

點擊創建的按鈕。

任何人都可以提供技術解釋嗎?

注1:標記只是一個帶有佔位符的空白頁 - 見下文。

注2:用Button代替LinkButton,代碼不會拋出異常並起作用。

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

什麼是例外? – Brandon 2011-03-24 14:43:30

+0

未將對象引用設置爲對象的實例。 – maxp 2011-03-24 14:45:33

+1

什麼行是拋出的異常? – Oded 2011-03-24 14:46:54

回答

0

看起來要麼PLACEHOLDER1或placeholder1.Controls爲空。這是給出你的代碼示例的NullReferenceException的唯一解釋。

0

我的猜測是該按鈕一旦從回傳回來就爲空。你基本上是刪除按鈕,並創建一個新的按鈕,這可能會刪除相關的事件。

只是爲了支持我的理論聯繫我嘗試這樣做:

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" }); 
} 

並沒有收到您收到的錯誤。

爲什麼你想像你一樣在運行時添加按鈕?

+0

你沒有收到錯誤,因爲按鈕,更不用說事件在回發時不存在了......刪除你的'IsPostBack'條件,它會發生。 – maxp 2011-03-24 15:15:57

+0

對,我試過你的代碼並收到錯誤。通過在Init/Load上動態創建按鈕,它僅存在於該特定請求中。一旦後發生(即點擊按鈕)按鈕和相關的事件爲空,這就是爲什麼你遇到了對象引用異常,它仍然需要存在於它已經事先做好的狀態回發 – 2011-03-24 15:20:41

+0

回發是生命週期的一部分:http://msdn.microsoft.com/en-us/library/ms178472.aspx – maxp 2011-03-24 15:25:00

0

如果您從OnLoad()中刪除對foo()的調用,我認爲代碼將開始工作。

原因是由於頁面生命週期中的事件順序。爲了使控件能夠引發事件,需要在ProcessPostData(),RaiseChangedEvents()和RaisePostBackEvents()事件發生之前創建控件(參見http://www.eggheadcafe.com/articles/o_aspNet_Page_LifeCycle.jpg以獲取頁面生命週期的圖形表示)。這些事件會在OnInit()之前但OnLoad之前()

由於您的代碼現在通過調用OnLoad()中的foo(),您將銷燬在OnInit()中調用foo()時創建的實例,因此當Event引發了不再存在的控件,因此「對象引用未設置爲實例」消息。