ASP.NET Web Server Control Identification
Every control that is included in an ASP.NET Web page must contain a unique identifier (ID). If you do not explicitly assign an ID to a control when you add the control to a Web page, ASP.NET creates a default ID for you. When a control is included inside a repeating control, such as the GridView, ListView, or Repeater control, a single control defined in markup often creates multiple instances of the control in the rendered HTML. The ASP.NET page framework provides a mechanism to make sure that each control in the rendered HTML for a page has a unique ID.
ASP.NET Web server controls include the following properties that act as identifiers:
UniqueID — this is an ID that is generated by ASP.NET for use by code that runs on the server.
ClientID — this is an ID that is generated by ASP.NET for use by client code (it is rendered as the value of the id attribute in HTML).
When the control is inside another control, the UniqueID property contains the value of the ID property concatenated with the name of the naming container. Controls that can act as containers for other controls generate a naming container, which is an ID namespace for their child controls. Controls that act as a naming container implement the INamingContainer interface. Examples of naming-container controls include the ListView and Repeater, DataGrid controls.
When the control is inside a data-bound control that creates multiple instances of the control, the value that you assign to the ID property is concatenated with the naming container and with an incrementing index.
Typically, you will not need to use the UniqueID property. For example, you should not write code that references controls by using a predicted value of the generated UniqueID property. You can read and pass the value of the UniqueID property to other processes, but you should not rely on it having a specific structure.
The ClientID property contains the value that is set as the id attribute of the control's rendered element in the HTML of the Web page. You use the id attribute to access the control from client script.
AutoID. The ClientID is generated as it was in the .NET Framework 3.5 and earlier versions. The ClientID property of the parent naming container and the ID property of the control are concatenated. In data binding scenarios that cause multiple iterations of a control to be rendered, an incrementing value is inserted before the control's ID and after the naming container IDs. Each segment is separated by an underscore (_).
Static. The ClientID property contains the value from the ID property without any modification. You use this value when you need the ClientID property to remain the same in all scenarios, and you have only one instance of the control on a page. You can also use this value to minimize the length of generated ClientID values, either to simplify client script or to improve performance by reducing the size of client script that is sent to the browser. When server controls are located in naming containers, the AutoID algorithm can generate very long ClientID values.
If you use the Static algorithm, it is possible for ASP.NET to create multiple HTML elements that have the same id attribute. In that case, the browser will render the page. However, if you try to use client script to access one of these elements by ID, an error will occur.
Predictable. This option is for use in data-binding scenarios. If the control is a data-bound control that has a ClientIDRowSuffix property, the ClientID value for each instance of the control is modified by appending the value of a field that you specify in the ClientIDRowSuffix property. For the GridView control, you can enter multiple field names separated by commas. If the data-bound control generates multiple rows but does not have a ClientIDRowSuffix property, or if you leave the ClientIDRowSuffix property blank, ASP.NET will use a sequential number as the ClientID suffix.
Inherit. The ClientID property is generated according to the ClientIDMode value of its NamingContainer control, or according to the ClientIDMode value of the page if the control is not in a naming container. This is the default value for the Control.ClientIDMode property.
You can set the default ClientIDMode value for a site in the Web.config file, and you can set the default value for a page in the @ Page directive. If you do not set a value at the site or page level, the default is Predictable. Because the default for controls is Inherit, the default generation mode is Predictable. (However, if you use Visual Studio to convert a Web project to ASP.NET 4 from an earlier version, Visual Studio sets the site default to AutoID in the Web.config file.)
The following example shows how to set the default ClientIDMode for a site in the Web.config file.
The following example shows how to set the default ClientIDMode for a page in the @ Page directive.
<%@ Page Language="C#" CodeFile="Default.aspx.cs"
Inherits="_Default" ClientIDMode="Static" %>
IDs for Controls That Are Not in Naming Containers
When a control is not inside a naming container or a data-bound control, ASP.NET uses the value of ID for the UniqueID property and the ClientID property. The following example shows a Label control that is not inside a naming container:
<asp:Label ID="Label1" runat="server"
When a control is not inside a naming container, the ClientIDMode property does not affect the generated ClientID property value. Therefore, all the IDs are the same regardless of what you set the ClientIDMode property to.
When the page runs, the Label1 control will have the following property values:
IDs for Controls That Are in Naming Containers
If a control is inside a naming container, ASP.NET generates the UniqueID property value and the ClientID property value by combining the ID values of all controls in the nesting hierarchy. However, if the ClientIDMode of any control in the nesting hierarchy is set to Static, the ID values of controls that are higher in the hierarchy are not included.
Common naming containers include master pages and content pages. The following example shows a Label control that is contained in a user control. The user control is inside a content page which itself is inside a master page.
Only relevant sections of the master page, content page, and user control are shown in the following examples.
The master page contains the following content placeholder:
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
The content page contains the following content section:
<uc:ExampleLabelControl ID="CustomUserControl1" runat="server" />
The user control contains the following Label control:
IDs for Data-Bound Controls
When a control is inside a data-bound control that generates repeated instances of the control, ASP.NET generates UniqueID and ClientID values for each instance of the control. The UniqueID value is generated by combining the naming container's UniqueID value, the control's ID value, and a sequential number. This is the case in controls such as the DataList, Repeater, GridView, and ListView controls.
ASP.NET generates ClientID values in a similar manner when the ClientIDMode property is set to AutoID. This can make it difficult to reference the control in client script, because you typically cannot predict the values of the sequential numbers that are used. If you want to access data-bound controls from client script, you can set the ClientIDMode property to Predictable. This makes it easier to predict what the ClientID values will be.
When you set the ClientIDMode to Predictable, you can also set the ClientIDRowSuffixDataKeys property to the name of a data field that is unique, such as the primary key in a database table. This causes ASP.NET to generate a client ID that will be easier to predict and reference in client script if you can predict data key values.
Setting the ClientIDMode property to Static in a data-binding scenario will not cause an exception. However, all the controls will have the same value for ClientID. In that case, you not be able to use the HTML id attribute to reference a specific control in client script.
<asp:XmlDataSource ID="XmlDataSource1" runat="server" XPath="Products/Product"> <Data> <Products> <Product ProductID="1" ProductName="Chai" /> <Product ProductID="34" ProductName="Ale" /> <Product ProductID="43" ProductName="Coffee" /> </Products> </Data> </asp:XmlDataSource> <asp:ListView ID="ListView1" ClientIDMode="Predictable" ClientIDRowSuffix="ProductID" DataSourceID="XmlDataSource1" runat="server" > <ItemTemplate> ProductID: <asp:Label ID="ProductIDLabel" runat="server" Text='<%# Eval("ProductID") %>' /> <br /> ProductName: <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Eval("ProductName") %>' /> <br /> <br /> </ItemTemplate> <LayoutTemplate> <div ID="itemPlaceholderContainer" runat="server"> <span ID="itemPlaceholder" runat="server" /> </div> <div> </div> </LayoutTemplate> </asp:ListView>
This example shows a data-bound control that is located on a Web page. If you put a data-bound control in a user-control, the portion of the ClientID value that precedes the control's ID value will vary depending on which page the user control is located on or which containing control it is located inside. This makes the ClientID values unpredictable even if you set the ClientIDMode property to Predictable. To remedy this, you can set the ClientIDMode of the data-bound control's parent container control to Static. When you set the ClientIDMode of a container control to Static and set the ClientIDMode property of a data-bound control within it to Predictable, the generated ClientID values for the data-bound control always begin with the ID of the container control regardless of which control or controls that container control itself is located in.
Referencing Controls in Server Code
In order to work with controls in code, you can get a reference to the control by using one of its ID properties.
Referencing Controls by ID
In code that runs on a Web server, you can directly reference a control by its ID property when the control is not in a repeating data control. For more information, see How to: Access Server Controls by ID.
If the page contains controls that are generated at run time, such as those in a template for the DataList, Repeater, or GridView controls, you cannot directly reference them by the value in the ID property, because the ID is not unique. Instead, in the code-behind class for the page, you can call the FindControl method of the control that is the container for the control that you want to reference. For more information, see How to: Access Server Controls by ID.