ASP.NET控制項編寫日記-當心“用過的控制項”!

來源:互聯網
上載者:User

“用過的控制項”就是指曾經加入過Controls(子控制項集合)中的控制項。這些“用過的控制項”再一次被加入Controls中時,可能造成控制項ID衝突,癥狀為:


中文版的錯誤資訊:

[HttpException (0x80004005): 找到多個具有相同 ID“c1:_ctl1:_ctl0:_ctl0”的控制項。Trace 要求控制項具有唯一的 ID。]

另附上英文版的錯誤資訊(便於使用google查詢英文資料):

[HttpException (0x80004005): Multiple controls with the same ID“c1:_ctl1:_ctl0:_ctl0”. Trace requires that controls have unique IDs. ]


由於出錯點位於.Net架構的基類中,調試跟蹤都不太方便,費了不少功夫才發現問題。這個錯誤的原因與ASP.NET中的控制項命名處理方式有關:

ASP.NET中的所有控制項都有Controls(子控制項集合)這個屬性,在將子控制項加入Controls中時,ASP.NET會對加入的控制項進行命名操作。如果該控制項已經指定了ID(即ID不為空白),則沿用該控制項已有的名字;如果控制項沒有指定ID(即ID為空白),則系統會為該控制項自動分配一個名字(自動命名的規則尚不清楚)。問題就出在這個自動分配的名字上,這個名字可能會與非自動命名控制項的名字相同(這個不知道算不算系統Bug?),於是就會出現上面的錯誤資訊。

系統自動指定的ID名字都以底線開頭,所以只要非自動命名的控制項名字都不以底線開頭,就可以有效避免發生重複。同一次進行自動命名的控制項之間是不會發生名字重複的,但在回傳情況下,控制項可能會建立兩次,這時候也容易發生名字重複。例如:

編寫這樣一個容器型控制項MyPanel,有兩個Panel為工具列和內容欄,其中都可以加入若干控制項。

用兩個ArrayList來存放加入的控制項。並在CreateChildControls()中將ArrayList中的控價加入Controls中,如下:

foreach (control c in m_List1)

{

    Controls.Add(c);

}

上述寫法實際上是有隱患的,如果在PostBack情況下,MyPanel可能被建立兩次,在第一次建立MyPanel時,系統為m_List1中的控制項分配了自動命名的ID,然後MyPanel又被建立了一次,而m_List1中的控制項來源於父類,可能並沒有重新建立,依然是那些已被自動命名的控制項(以底線開頭的ID),這時系統不會為m_List1中的控制項自動命名,這些控制項的名稱就很容易與系統中的自動命名控制項重複,發生系統錯誤。

上面說的這個問題比較隱蔽,但也比較容易避免,比如採用如下寫法就可以:

foreach (control c in m_List1)

{

    c.ID = String.Empty;

    Controls.Add(c);

}

將控制項的ID置為空白,系統就會為控制項分配自動命名的ID了。但這個方法會清空非自動命名控制項的ID,所以還可以加上判斷,當控制項ID以底線開頭時,才進行清空。這裡也要提醒大家,對控制項指定ID時,不要指定以底線開頭的名稱,以免重複!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.