Welcome to AspAdvice Sign in | Join | Help

Accessing ClientID or UniqueID too early can cause issues

Edit:

Here’s also the Connect link (I reported this as a suggestion)
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=254373

--

 

 I've seen lately a few issues on newsgroups related to ASP.NET 2.0 cases where ClientID or UniqueID of a Control is accessed before the control tree is fully constructed, which leads to rendered ClientID and UniqueID being wrong. Final issue is that these prevent postback events from working as UniqueID is used with postback data routing. Here's a simple case to repro it.

Assume we have a  DataGrid with a Button.

<asp:DataGrid ID="DataGrid1" runat="server"  AutoGenerateColumns="false" OnItemCreated="DataGrid1_ItemCreated" >
     <Columns>
        <asp:TemplateColumn>
           <ItemTemplate>
             <asp:Button ID="Button1" runat="server" Text="Click me" OnClick="Button1_Click" />
           </ItemTemplate>
        </asp:TemplateColumn>
     </Columns>
</asp:DataGrid>

And relevant code

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            ArrayList list = new ArrayList();
            list.Add(1);
            list.Add(2);
            list.Add(3);

            DataGrid1.DataSource = list;
            DataGrid1.DataBind();
        }
    }

    protected void DataGrid1_ItemCreated(object sender, DataGridItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            //Touching the clientID too early causes rendered ids to be wrong
            // which also impacts on postback routing etc etc

            //comment the line(s) to make clicks work
            string s = e.Item.FindControl("Button1").ClientID;
            //string s = e.Item.FindControl("Button1").UniqueID;
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        Response.Write("Button1_Click");
    }
   

The lines in ItemCreated accessing ClientID or UniqueID are the catch. If they (either or both) are uncommented, the grid renders as

 <table cellspacing="0" rules="all" border="1" id="DataGrid1" style='border-collapse:collapse;'>
 <tr>
  <td>&nbsp;</td>
 </tr><tr>
  <td>
                    <input type="submit" name="Button1" value="Click me" id="Button1" />
                </td>
 </tr><tr>
  <td>
                    <input type="submit" name="Button1" value="Click me" id="Button1" />
                </td>
 </tr><tr>
  <td>
                    <input type="submit" name="Button1" value="Click me" id="Button1" />
                </td>
 </tr>
 </table>

However, if you comment the lines you'll see

<table cellspacing="0" rules="all" border="1" id="DataGrid1" style='border-collapse:collapse;'>
 <tr>
  <td>&nbsp;</td>
 </tr><tr>
  <td>
                    <input type="submit" name="DataGrid1$ctl02$Button1" value="Click me" id="DataGrid1_ctl02_Button1" />
                </td>
 </tr><tr>
  <td>
                    <input type="submit" name="DataGrid1$ctl03$Button1" value="Click me" id="DataGrid1_ctl03_Button1" />
                </td>
 </tr><tr>
  <td>
                    <input type="submit" name="DataGrid1$ctl04$Button1" value="Click me" id="DataGrid1_ctl04_Button1" />
                </td>
 </tr>
 </table>

The difference in behavior is that in other case Button's Click event is raised while in the other it isn't.

Based on my current investigation this relates to UniqueID getting cached too early due to early access (it is implemented in get accessor of ClientID and UniqueID properties) or that's how I've understood it. In ItemCreated the DataGridItem isn't yet added to Controls collection of the grid, which means that the full control tree from the Button to the Page isn't final. Accessing ClientID or UniqueID at this point causes the issue.

Cause itself is clear: Accessing ClientID and UniqueID too early is wrong but question is that is the behaviour too unintuitive as-is? Should it not cache the id till the control tree is done or should it throw an exception (that could be exaggerated but also an option )? I think that just accessing a property causing this type of behaviour is a bit too "mystical". :-)

I do understand it, but seems that there are people getting quite confused because of it. And because of no exceptions etc, it might be harder to debug and correct. Solution itself is very simple once you understand the issue.

Opinions?

Published Sunday, January 28, 2007 1:07 PM by joteke
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Accessing ClientID or UniqueID too early can cause issues

Thank you...
Tuesday, November 25, 2008 2:52 AM by r&#252;ya tabiri

# re: Accessing ClientID or UniqueID too early can cause issues

Is there a workaround for this?
Tuesday, May 12, 2009 11:43 AM by Casey

Leave a Comment

(required) 
required 
(required) 
Enter the code you see below