Controlling our ClientIDs in ASP.NET 4
December 10, 2010 § Leave a comment
Introduction to ClientIDs in ASP.NET 4
ClientIDMode property that lets you define how client ids are maintained in your ASP.NET code.
What are ClientIDs?
Each control on an ASP.NET page has two names. The first is the control name, and this is the name of that object as it relates to code on the server side. When you want to access the text property of a text box you will use the control name to do so. In the .aspx file you would declare the text box control:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
And in your code behind you would refer to it as so:
string newName = TextBox1.Text;
<div id="topPanel"> <input name="TextBox1" type="text" id="TextBox1" /> <input type="submit" name="Button1" value="Button" id="Button1" /> </div>
This isn’t too bad to work with since the client id matches the control id we are used to. But when you put these same controls inside a content placeholder as part of a master page (or a grid, or any other control container), a whole new set of client ids appear. This is because they now have a nested relationship.
<div id="ctl00_ContentPlaceHolder1_topPanel"> <input name="ctl00$ContentPlaceHolder1$TextBox1" type="text" id="ctl00_ContentPlaceHolder1_TextBox1" /> <input type="submit" name="ctl00$ContentPlaceHolder1$Button1" value="Button" id="ctl00_ContentPlaceHolder1_Button1" /> </div>
'ctl00_ContentPlaceHolder1_Button1' instead of just
'Button1'. This leads to messy, hard to maintain code.
How the Control Tree Works
All controls on your page are organized in a tree structure on the page by ASP.NET. In our first example, all of the controls were direct children of the form itself. In our second example they became children of the content placeholder control, which itself was a child of the form. This tree represents the hierarchy, or family structure, of the controls and how they related to one another.
ASP.NET generates names for your controls at runtime based on this tree. If there is just one level, they are given names that are the same (or similar) to their control id. If, you have controls nested, then the name is a concatenation of the controls name, and all of its parents, in one long string. This is to avoid any naming conflicts between all of the controls on the page.
This doesn’t look hard in our simple sample, but take a look at a dynamically generated grid with a hundred rows and ten columns and your head will explode (sample not provided because we are concerned with your safety).
How to Control your Client ID
ASP.NET 4 has a new feature that lets you control the client ids generated for your controls. You can control this at the application level, the page level, or at the control level, to suit your needs. You can control this behavior by setting a property called
There are four options for this new property:
- Static: This forces the client id to always match the control id (or the ID parameter on the control). This is very nice and gives you a consistent naming structure on the client and the server, but does leave open the problem of conflicting control names in some scenarios. This is my preferred setting when I can get away with it.
- Predictable: This uses the same algorithm as the AutoID mode to generate names, but it avoids the crazy parent control prefixes like ct100_. This setting makes sure you have no conflicts in names, but keeps them somewhat cleaner. When working with a container control, like a grid, that will have a lot of child controls you can force your own prefix (example: salesGrid), giving you some control over your code readability. To do this you would set the
ClientIDRowSuffixproperty on the parent control.
- Inherit: This mode tells the control to inherit its naming behavior from its naming container (which may not necessarily be its control container).
How to Use It
To declare this for the entire web application you have to add a setting to your web.config in the
<system.web> <pages clientIDMode="AutoID"></pages> </system.web>
In this example I set the behavior to
AutoID. Remember that this feature is only supported in ASP.NET 4, so you have to change the .NET framework version of your project in the project properties before this will work.
To change the naming behavior for just a single page (perhaps you want to migrate one page at a time from the old way to the new way) you would add a property to the page declaration in the aspx file.
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Code.WebForm1" ClientIDMode="Inherit" %>
In this example we set the property for all controls on this page to
And finally, to change how a single control might name itself and its children (most likely on a grid or some sort of control) you would add a property to the controls declaration:
<asp:Button ID="Button1" runat="server" Text="Button" ClientIDMode="Static" />
With ASP.NET 4 you can now use the ClientIDMode property to control how ASP.NET names your controls. The setting can be declared for the whole application, just a page, or a single control. You can set it to continue naming controls the old way, forcing a specific control name, or to use a new cleaner way to name them. You also have the option of telling a control to inherit the naming behavior from its naming parent.