从今天开始会有几篇日志,介绍 ASP.NET 4 Web Forms 中的一些重要变化,即生成干净的、标准兼容的、CSS友好的标记。今天介绍对服务器控件向客户呈现"ID"属性的更好控制。
干净的、基于标准的、CSS友好的标记
使用 ASP.NET Web Forms 的开发人员经常报怨的一件事情就是当使用服务器控件时,他们不能轻易地拥有产生干净的、CSS友好的输出和标记的能力。这些抱怨包括:
ASP.NET 4 为构建兼容标准的页面提供了更好的支持。内置的 <asp:> 服务器控件现在可以产生更干净的标记并支持CSS式样,从而解决了上述所有问题。
升级现有 ASP.NET Web Forms 应用程序时的标记兼容性
一个常见的问题就是,人们在听到 ASP.NET 4 带来的更干净标记时会问“很好——但我现存的应用程序怎么办?这些变化/改进在我升级时会带来破坏吗?”
为了确保不会破坏现存 ASP.NET Web Forms 应用程序的标记和式样,我们启用了一个配置标志——controlRenderingCompatibilityVersion——在 web.config 内部这样就能让你决定你是否想使用新的默认于ASP.NET 4应用程序中更干净的标记方法,或者为了兼容性的原因呈现和旧版本相同的标记:
当 controlRenderingCompatibilityVersion 标志设置为 "3.5",你的应用程序和服务器控件将会默认呈现VS2008和.NET3.5产生的标记。当 controlRenderingCompatibilityVersion 标志设置为 "4.0",你的应用程序和服务器控件会严格地遵守XHTML1.1规范,拥有更干净的客户端ID,呈现符合语义正确性,并移除多余的内联样式。
这个标志对使用 ASP.NET 4 构建的所有新的 ASP.NET Web Forms 应用程序都默认为 4.0。任何旧版本应用程序在使用VS2010升级后都会被升级向导自动把 controlRenderingCompatibilityVersion 标志设置为 3.5,以保证向后兼容。随后你可以可选地改变它(在应用程序级别,或者对每个页面或目录级别),如果你使用 CSS 并利用了新的标记呈现的话。
更干净标记主题:客户端 ID
拥有干净的、可预料的HTML 元素的 ID 属性是开发人员一直对 Web Forms 问的问题(像"ctl00_ContentPlaceholder1_ListView1_ctrl0_Label1"的ID值非常不受欢迎)。拥有对呈现的ID值的控制使得编写客户端JavaScript脚本变得非常容易,也使得使用 CSS 样式化元素变得更加容易,在大页面中可以减少产生的标记的大小。
控件新的 ClientIDMode 属性
ASP.NET 4 在 Control 基类上支持新的 ClientIDMode 属性。ClientIDMode 属性指示控件在呈现时应当如何产生客户端ID值。ClientIDMode 属性支持4个可能的值:
ClientIDMode 属性可以直接在控件上设置(或在容器控件内部设置,这样内部的子控件会自动继承此设置):
或者可以在页面或用户控件级别指定(使用 <%@ Page %> 或 <%@ Control %> 指令),这时页面/用户控件内部的控件都会继承这个设置(控件可以覆盖这个值):
或者可以在应用程序的 web.config 文件内部设置,整个应用程序内部的页面都会继承这个设置(也可以覆盖):
这样就拥有了定制/覆盖命名行为的弹性。
示例:使用 ClientIDMode 属性控制非列表控件的 ID
让我们看看如何使用新的 ClientIDMode 属性来控制页面内部呈现元素的ID。创建一个叫做"SimpleControlExample.aspx"的简单页面,它基于叫做"Site.master"的母版页,页面中有一个 <asp:label> 控件,其值为"Message",这个控件置于叫做 "MainContent" 的 <asp:content> 容器控件中:
在后置代码中添加一些简单的代码,比如像下面这样在运行时动态地填充标签的 Text 属性:
如果使用 ASP.NET 3.5 运行这个应用程序(或者使用配置为使用 3.5 呈现或ClientIDMode=AutoID的 ASP.NET 4 应用程序),那么产生并发送到客户端的标记会像下面这样:
这个ID是唯一的(这挺好),但"ctl00"前缀让它显得比较丑陋(这不好)。
使用 ASP.NET 4,服务器控件默认使用 ClientIDMode="Predictable" 呈现它们的 ID。这确保了 ID 值仍然是唯一的,不会在页面上冲突,同时它让 ID 不再冗长更可预料。这意味着 <asp:label> 控件在 ASP.NET 4 中默认会产生像这样的标记:
注意,"ctl00" 前缀不见了。因为"Message"控件位于"MainContent"容器控件内部,默认地它的ID被设置为"MainContent_Message"以避免和页面其他控件出现潜在冲突。
使用 ASP.NET 4 且 ClientIDMode 设置为 "Static" 的标记呈现
有时不想让ID值层层嵌套,而是想和设置的一样呈现出来。要想做到这一点,可以使用 ClientIDMode=static,这样呈现的ID将会和在服务器控件上设置的完全相同。这将会呈现出下面的内容:
示例:使用 ClientIDMode 属性控件数据绑定控件的 ID
数据绑定的列表/网格控件在过去使用 Web Forms 自动产生ID时是最难以使用和样式化的。让我们看看使用 ASP.NET 4 定制 ListView 控件 ID 的场景。
下面的代码片断是一个 ListView 控件的例子,它显示了一个数据绑定集合的内容:
接着在后置代码中编写像下面这样的代码,动态地将数据源绑定到 ListView 中:
在运行时它默认会产生一个
添加客户端ID到每一项
现存假设我们想把客户端ID添加到输出中,这样我们能够通过 JavaScript 编程访问每一个
第一步是在模板内的每一个
ASP.NET 4 默认会呈现像下面这样干净的 ID(没有类似于 ctl001 这样的ID呈现):
使用 ClientIDRowSuffix 属性
上面的模板为每一个
现在不是有像"1", "2", "3" 这样的后缀,而是在ID中嵌入了 Airport.Code 值:
ClientIDRowSuffix 属性也能够用于其他数据绑定控件,如 GridView。
总结
ASP.NET 4 使得服务器控件和 Web Forms 应用程序能够生成更加干净的 HTML 标记。今天介绍了如何轻易地控制服务器控件在客户端呈现的ID值。在接下来的日志中我将介绍 ASP.NET 4 其他的一些标记改进。