Controlling our ClientIDs in ASP.NET 4

Introduction to ClientIDs in ASP.NET 4

Microsoft has released ASP.NET 4 with a lot of new features. One that seems small on the surface is a feature that I am very excited about. It has the potential to really clean up my code, and make JavaScript a lot easier for me to write and maintain. This little feature that could is the 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;

But when it comes to referring to this text box from within the browser (most likely with JavaScript or a framework on JavaScript like JQuery) ASP.NET generates a client side ID for it. This is called the client id. In many scenarios this client id is the same as the control id. If you view the source of your site, you will see this in action. If we put a textbox and a button on a normal .aspx page you will see this for the HTML:

  <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>

So now in my JavaScript I have to refer to a control called '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 ClientIDMode.

There are four options for this new property:

  • AutoID: This follows the old behavior, resulting in long, complex, and extremely unique client ids. You might use this mode if this behavior doesn't bother you, or perhaps you have some legacy JavaScript you don't have time to update yet.
  • 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 ClientIDRowSuffix property 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 section.

  <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 Inherit.

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" />

Summary

Prior to ASP.NET 4 client ids were generated for you, sometimes resulting in ids that were very hard to work with. This behavior did make sure that with all of the nested controls on the screen you never ended up with a naming conflict on a control, it did result in some hairy JavaScript.

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.

Related Articles





About the Author

Brian Prince

Brian H. Prince is an Architect Evangelist with Microsoft focused on building and educating the architect community in his district. Prior to joining Microsoft in March 2008, he was a Senior Director, Technology Strategy for a major mid-west partner.

Further, he is a co-founder of the non-profit organization CodeMash (www.codemash.org). He speaks at various regional and national technology events including TechEd.

Brian holds a Bachelor of Arts degree in Computer Science and Physics from Capital University, Columbus, Ohio. He is also an avid gamer.

Comments

  • Great Post!

    Posted by SamBrace on 12/10/2010 06:16pm

    Brian - This is an excellent article! The staff at SSWUG.org liked it so much that we featured it on the site. 
    
    Keep providing great information on ASP.NET!

    Reply
  • Provide more examples

    Posted by macspudster on 12/07/2010 02:00pm

    Your article clearly favors the ClientIDMode mode "AutoID" though you state you like "Static". The conclusion that you 'favor' the ClientIDMode "AutoID" is that you lack examples for all the modes except AutoID. Case in point is the ClientIDMode "Predictable". You mention what it does, but don't show examples. The short of it being you need to provide examples for all 4 ClientIDMode modes, not just one (which is barely an example at that). And, "example" means to show both the server-side ASPX and the final HTML output.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Hurricane Sandy was one of the most destructive natural disasters that the United States has ever experienced. Read this success story to learn how Datto protected its partners and their customers with proactive business continuity planning, heroic employee efforts, and the right mix of technology and support. With storm surges over 12 feet, winds that exceeded 90 mph, and a diameter spanning more than 900 miles, Sandy resulted in power outages to approximately 7.5 million people, and caused an estimated $50 …

  • Today's competitive marketplace requires the organization to frequently release and deploy applications at the pace of user demands, with reduced cost, risk, and increased quality. This book defines the basics of application release and deployment, and provides best practices for implementation with resources for a deeper dive. Inside you will find: The business and technical drivers behind automated application release and deployment. Evaluation guides for application release and deployment solutions. …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds