【茶包射手日記】GridView Id雙胞奇案
| | 0 | | ![]() |
網友FrankWu在一篇留言中提到有趣的現象:
在套用jQueryClientIdEnhancement.RegisterExtScript()之後,GridView內原本沒有Id的HTML元件如<table>、<tr>、<td>開始出現id=”GridView1_ctl01”的屬性,甚至冒出<table>有兩個id的情形;若不呼叫RegisterExtScript就不會有此問題...
經實測,果真如此! 再深入做了實驗,發現問題是程式存取GridView內部控制項的ClientID屬性搞出來的,我寫了一個極簡單的網頁來驗證:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<string> l = new List<string>() { "Data" };
GridView1.DataSource = l;
GridView1.DataBind();
if (Request["clientid"] != null)
{
string cid = GridView1.Controls[0].ClientID;
}
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>
</form>
</body>
</html>
當呼叫Test.aspx時,產生的HTML符合預期:
<table cellspacing="0" rules="all" border="1" id="GridView1"
style="border-collapse:collapse;">
<tr>
<th scope="col">Item</th>
</tr><tr>
<td>Data</td>
</tr>
</table>
若呼叫Test.aspx?clientid=yes,程式會去讀取GirdView1.Controls[0].ClientID,此時傳回的HTML就會看到<table>除了原有的id=”GridView1”外,最前方又多了一組id=”GridView1_ctl00"。
<table id="GridView1_ctl00" cellspacing="0" rules="all" border="1"
id="GridView1" style="border-collapse:collapse;">
<tr>
<th scope="col">Item</th>
</tr><tr>
<td>Data</td>
</tr>
</table>
用Reflector追查,發現呼叫ClientID時會觸發EnsureID(),TemplatedControl裡原本不另給Id的HTML元素(例如GridView中的<table>)會因此自動產生唯一識別碼,但在本案例中,<table>原本就有id="GridView1”,再加上自動產生的id便鬧出了雙胞。由於元素有兩個id並不符合HTML規範,我認為這算是Bug,只是,用GridView1.Controls[n]去存取這些平時根本不外露的內部控制項是很罕見的用法,因此影響有限,或許也排不上修復清單吧! 但我還是順手在Connect提報了一則Bug Report,算為ASP.NET產品的改善盡點心意。
Comments
Be the first to post a comment