
This is the sixteenth article in the
series on the upcoming VS 2010 and .NET 4 release.
Today’s post is the first in a series that tells about important changes we made with Web Forms in ASP.NET 4 for generating clean, compliant CSS-friendly markup standards. Today I will talk about the work we have done to provide better control over the “ID” attribute generated by the server controls for the client.
Generate clean, standards-compliant CSS-friendly markup
One of the most common developer complaints was the inability to generate a normal layout for server controls in ASP.NET Web Forms. Here is a list of specific problems in the previous version of ASP.NET:
- Auto-generating the ID attribute in HTML makes it difficult to work with JavaScript and CSS.
- Using tables instead of semantic markup for some controls (for example, asp: menu), which is ugly for styling.
- Some controls generated lower case styles, even when no style properties were explicitly specified.
- ViewState was often quite large, which is far from ideal.
ASP.NET 4 provides improved support for building standards-compliant page out of the box. Now, the ASP.NET 4 built-in <asp:> server control generates cleaner markup and supports CSS styling, which eliminates all of the above problems.
')
Markup Compatibility During Upgrading Existing ASP.NET Web Forms Applications
A common question people ask when they hear about the cleaner markup that appeared in ASP.NET 4 is “Great, but what about my existing applications now? Will these innovations break everything when I update the project? ”
To make you sure about the immutability of the layout and styling in existing ASP.NET Web Forms applications, we added a configuration flag -
controlRenderingCompatbilityVersion, to the web.config, which allows you to decide which version of the markup generator to use:
When the
controlRenderingCompatbilityVersion flag
is set to “3.5”, your application and server controls by default draw the markup corresponding to .NET 3.5. When the
controlRenderingCompatbilityVersion flag
is set to “4.0”, your application and server controls generate semantic markup conforming to the XHTML 1.1 standard, cleaner client IDs, and there are no extraneous lowercase styles.
By default, this flag is equal to 4.0 for all new ASP.NET Web Forms applications built using ASP.NET 4. For all other, earlier applications that are updated with VS 2010, we automatically set the
controlRenderingCompatbilityVersion flag to 3.5. Later, you can easily change its value, both at the level of the entire application, and in the web.config file separately for each page or for the entire directory.
Client ID
The ability to have a clean, predictable ID attribute for the generated HTML element is what developers have asked for for a long time for Web Forms (ID values such as “ctl00_ContentPlaceholder1_ListView1_ctrl0_Label1” are not very popular). Having control over the value of the ID, it becomes easier for you to write JavaScript, use CSS, and also reduce the amount of markup on large pages.
New property for ClientIDMode controls
ASP.NET 4 supports the new
ClientIdMode property in the base Control class. The
ClientIdMode property
indicates how the control should generate a client ID. The
ClientIdMode property supports four possible values:
- AutoID - generates according to the .NET 3.5 principle (autogenerated ID still adds ctrl00 prefix for compatibility)
- Predictable (default) - cuts the “ ctl00 ” on the ID string and, if it is a list or container, it adds the parent ID to its children (id = ”ParentControl_ChildControl”)
- Static - gives full control over the name of the control to the developer, no matter what he specifies for the ID, everything will be displayed as a result.
- Inherit — Tells the control to use the parent control's naming mode.
The ClientIDMode property can be set directly to any control or in a container, and then the internal elements will be with the inherited settings:
Or it can be set at the entire page level using the directives <% @ Page%> or <% @ Control%>, in this case, the controls inside the page or the user control inherit the settings and can optionally overload them.
Or it can be installed in the web.config of the application, in this case, the pages in the application will inherit the settings and, in the same way, may overload them.
All this gives you the flexibility to customize or overload the naming behavior the way you want it.
Example: Using the ClientIdMode Property for Non-List Controls
Let's take a look at how you can use the
ClientIdMode property for the controls on the page, setting “ID”. For demonstration, we will create a simple page, call it “SingleControlExample.aspx”, which is based on the master-page “Site.Master”, and contains one <asp: label> element with the ID “Message” located in <asp: content> with named “MainContent”:
In our code-behind file we add simple code, as shown below, to set the text of the Label dynamically:
If we run the application using ASP.NET 3.5, or we configured the ASP.NET 4 application to use rendering from version 3.5, or set ClientIdMode = AutoID, then the generated markup sent to the client will look like this:
The ID is unique, which is good, but ugly because of the “ctl100” prefix, which is not particularly pleasing.
Markup generation when ClientIdModel is set to “Predictable”
With ASP.NET 4, default server controls are generated using ClientIdMode = ”Predictable”. This allows you to be sure that all ID values are unique and there are no conflicts on the page, at the same time ID is less verbose and more predictable. This means that the generated markup of the <asp: label> control, by default, in ASP.NET 4, will look like this:
Note that the prefix “ct100” has disappeared. Since the “Message” control is located in the “MainContent” container, by default, its ID will be prefixed with “MainContent_Message” to prevent potential collisions with other controls on the page.
Markup generation when ClientIdModel is set to “Static”
Sometimes you do not want the ID values not to be nested hierarchical, but simply to go with the value that we want to set:
All this gives us the ability to fully control the value of client ID controls.
Example: using the ClientIdMode property for data-related lists
Data-related lists or grids have historically been difficult to use or customize styles when working with automatically generated IDs in Web Forms. Now let's take a look at the script where we configure the ID for the ListView in ASP.NET 4.
Below is a ListView code snippet that displays content from a related collection, in our case airports:
Next, we can write code in the code-behind file to dynamically link the list of airports to the ListView:
At run time, the default list will look like <ul>. Notice that the <ul> and <li> elements in the ListView are not server-side controls, and there is no ID for them in the markup:
Add client ID for each line
Let's imagine that we need to add a client ID, for programmatic access to each <li>, via JavaScript. We want these IDs to be unique, predictable, and identifiable.
It is necessary to mark each <li> in the template as a server control, setting the attribute runat = ”server” to it and give each id “airport”:
By default, ASP.NET 4 will generate a clean ID, as shown below, there will be no ctl001:
Use the ClientIDRowSuffix property
Our template above presented now generates unique IDs for each <li> element, but if we programmatically access it via JavaScript, we would like the ID to contain the airport code. The good news is that you can do this very simply using the new
ClientIDRowSuffix property in an associated ASP.NET 4 control:
To do this, set the
ClientIDRowSuffix property to “Code” in our ListView. It tells ListView to use the associated “Code” property from our Airport class, during ID generation:
And now, instead of the suffix “1” or “2”, we get the value Airport.Code (_CLE, _CAK, _PDX):
You can use
ClientIDRowSuffix in any other elements that have a link to the data, for example a GridView.
Results
ASP.NET allows you to generate much cleaner HTML markup for server controls.
In the next article I will tell about other innovations that have affected the markup in ASP.NET 4.