ASP.NET 和 XHTML

更新:2007 年 11 月

ASP.NET 允许您创建符合 XHTML 标准的网页。XHTML 是将 HTML 定义为 XML 文档的万维网联合会 (W3C) 标准。创建符合 XHTML 标准的网页具有以下优点:

  • 它可以保证页中的元素都采用了正确的格式。

  • 由于许多浏览器逐渐转向支持 XHTML,因此创建符合 XHTML 标准的页有助于确保您的页面在所有浏览器中具有一致的呈现格式。

  • 使用 XHTML 有助于使页更便于符合辅助功能标准。

  • XHTML 是可扩展的,它允许定义新的元素。

  • 当网页要由计算机进行处理,而不是供用户阅读时,XHTML 页更易于以编程方式读取,并且可以使用转换来操作文档。

W3C 已确定了数个 XHTML 标准级别:XHTML 1.0 Transitional、XHTML 1.0 Frameset、XHTML 1.0 Strict 和 XHTML 1.1。XHTML 1.1 规范是这些级别中最严格的。XHTML 1.0 Frameset 和 Transitional 规范定义了基于 XML 的 HTML 标记,但允许某些常用的构造。可以使许多现有网页符合 XHTML 1.0 Frameset 或 Transitional 规范,但是如果不进行大幅度的修订来替换使用这些规范中不允许的构造实现的功能,则无法满足 XHTML 1.0 Strict 或 XHTML 1.1 规范的要求。

有关 XHTML 标准的更多信息,请参见 W3C 网站 上的 XHTML 1.0 规范第二版。

符合 XHTML 标准的 ASP.NET 功能

XHTML 定义元素和属性的方式比 HTML 更加严格。现在,默认情况下 ASP.NET 生成的所有标记和 ASP.NET 中包括的 Web 服务器控件都符合 XHTML 1.0 Transitional 标准。在许多情况下,ASP.NET 生成的标记也符合 XHTML 1.1 标准。除非另行说明,本主题中提及的 XHTML 标准包括 XHTML 1.0 和 XHTML 1.1。

一些不同于 HTML 的 XHTML 规则如下:

  • 所有元素要么包括一个显式结束标记,要么包括一个自结束标记(带 />)。

  • 标记和属性名称均以小写形式呈现,且属性值括在双引号中。例如,如果您在页面上使用一个 GridView 控件,则在呈现该页面时,GridView 控件便会发出符合 XHTML 标准的 HTML 网页。生成的所有元素都使用显式的开始标记和结束标记(或自结束标记),且属性值括在双引号中。

  • 格式设置信息只通过级联样式表的样式呈现。为了支持此标准,只要页面中包含一个 XHTML DOCTYPE 元素,ASP.NET 控件便不会呈现 font 元素或属性(如 bgcolor),因为那样会违反 XHTML 标准。

  • 在 ASP.NET 中,如果控件生成 ID(如在 RepeaterGridView 和其他控件中那样),则 ID 的格式也将符合 XHTML 1.0 Transitional 标准。

  • ASP.NET 会为 form 元素动态添加一个 action 属性。默认情况下,form 元素包含一个 name 属性,这在 XHTML 1.0 Transitional 规范中是允许的。这有助于保持与现有应用程序的向后兼容性,因为现有应用程序依赖于使用窗体名称定位 form 元素的客户端脚本。

    exc57y7e.alert_note(zh-cn,VS.90).gif说明:

    form 元素中的 name 属性在 XHTML 1.1 标准中是不允许的。您可以将应用程序配置为不呈现 name 属性。有关详细信息,请参见本主题后面的“控制 ASP.NET 页和控件的 XHTML 呈现”。

  • 由于 XHTML 要求所有元素都要包含在一个容器元素中,因此 ASP.NET 控件(例如 input 元素)均在 div 元素中呈现。其中包括为控件(例如 TextBoxCheckBoxRadioButton 控件)所呈现的 HTML 标记。此外,还包括一些隐藏字段,如用于存储视图状态数据的元素。

  • ASP.NET 将对字符进行编码,例如,将 & 字符编码为 &。这包括为引用 ECMAScript 而生成的 URL 和编码值的内容,如视图状态。

  • 任何以页面形式呈现的 script 元素都使用相应的 type 属性〔例如,type="type/javascript"〕,且不包括 language 属性。这适用于那些由需要客户端脚本来执行回发的页面或控件创建的脚本,还适用于那些由 RegisterHiddenField、RegisterStartupScript 和 RegisterClientScriptBlock 方法创建的脚本,上述控件包括 HyperLink、LinkButtonCalendarTreeView 控件和验证程序控件。您创建的脚本块不会自动使用 type 属性修改。

  • 如果 ASP.NET 呈现脚本块,则脚本块的内容呈现在 XML (HTML) 注释中。

控制 ASP.NET 页和控件的 XHTML 呈现

在某些情况下,您可能希望 ASP.NET 控件使用 XHTML 1.1 规范所指定的更严格的格式来呈现标记。默认呈现方式包括一些不符合 XHTML 1.1 规范的标记。例如,XHTML 1.1 标准禁止在 HTML form 元素中使用 name 属性。

反而言之,您可能希望 ASP.NET 呈现不符合 XHTML 1.0 Transitional 规范的标记。现有页所依赖的标记或属性在 ASP.NET 早期版本中受支持,但它们不符合 XHTML 标准,这是一种典型情况。

您可以将您的网站配置为以下面三种方式呈现标记:

  • Legacy(与在 ASP.NET 早期版本中呈现标记的方式类似)

  • Transitional (XHTML 1.0 Transitional)

  • Strict (XHTML 1.0 Strict)

有关更多信息,请参见如何:在 ASP.NET 网站中配置 XHTML 呈现

exc57y7e.alert_note(zh-cn,VS.90).gif说明:

提供呈现旧标记的选项主要是为了帮助您将现有页迁移到当前版本的 ASP.NET 中,在将来的 ASP.NET 版本中可能不支持此选项。

Legacy 呈现方式

在将呈现方式设置为 Legacy 时,ASP.NET 页和控件会将其呈现方式更改为早期版本的 ASP.NET 中的行为。这些更改包括以下内容:

  • 呈现的 form 元素具有 name 属性。

  • ASP.NET 不会自动将 form 元素内的 div 元素呈现为控件容器。

  • 验证程序控件将被呈现为具有自定义属性(如 controltovalidate)的 span 元素。

  • 除非显式包括,否则 img 元素将不会呈现 alt 和 src 属性。

  • 如果需要支持自动回发行为,控件将呈现 language 属性(例如,language="javascript")。

  • 对于呈现 div 元素的控件(如 Panel 控件)来说,如果控件的 Wrap 属性被设置为 false,则会包括控件的 nowrap 属性。

  • ImageButton 控件呈现 border 属性。

  • 页面中呈现的任何 br 元素都会以 <br> 形式呈现。但是,如果显式包括 <br /> 标记,页面便会按原样呈现。

  • 如果设置了 BackColor 属性,则 DataGridCalendar 控件便会在呈现的 table 元素中包括 bordercolor 属性。

指定 DOCTYPE 元素和 XHTML 命名空间

有效的 XHTML 网页必须包含一个 DOCTYPE 声明,该声明将页面标识为 XHTML 页,并引用其要遵循的 XHTML 架构。页面还必须在引用 XHTML 命名空间的 HTML 标记上包括各个属性。在呈现页面时,ASP.NET 不会自动创建 DOCTYPE 声明。因此,需要使用适当的 XML 命名空间引用来创建 DOCTYPE。

exc57y7e.alert_note(zh-cn,VS.90).gif说明:

可视化设计器(例如 Visual Studio)通常包括包含 DOCTYPE 声明的默认页模板。如果使用的是可视化设计器,请检查其是否使用了所需的 DOCTYPE 声明来创建新页。 有关更多信息,请参见Visual Web Developer 中的 XHTMLVisual Web Developer 中的 XHTMLVisual Web Developer 中的 XHTML.

下面的代码示例演示一个可添加到页面中的 DOCTYPE 声明。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >

通过不自动生成 DOCTYPE 声明,ASP.NET 为对于不同的 HTML 标准采用不同的兼容级别的浏览器保留了更大的呈现灵活性,所采用的 HTML 标准可以在 DOCTYPE 声明中指定。

exc57y7e.alert_note(zh-cn,VS.90).gif说明:

如果移除 DOCTYPE 声明,将不会满足 XHTML 遵从性。该页将不被视为 XHTML 页并且不会引用 XHTML 架构。

许多浏览器也会根据是否存在 DOCTYPE 声明和 XML 命名空间声明来更改其呈现方式。如果存在这些元素,浏览器通常使用基于标准的呈现方式。如果不存在这些元素,许多浏览器将使用浏览器特定规则来进行呈现,所使用的规则根据浏览器类型的不同而异(有时也称为以“突发模式”呈现),因此会导致不可预测的呈现方式。

同样,还可以控制页面的 MIME 类型。默认情况下,页面会将 MIME 类型设置为 text/html。但是,通过在 @ Page 指令中设置 ContentType 属性,可以重写页面的 MIME 类型,如下面的代码示例所示。

<%@ Page Language="VB" ContentType="application/xhtml+xml" %>
<%@ Page Language="C#" ContentType="application/xhtml+xml" %>

带有所需 XHTML 元素的 ASP.NET 示例页

下面的代码示例演示一个符合 XHTML 标准的简单 ASP.NET 页。

<%@ Page Language="VB" AutoEventWireup="false" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<script runat="server">
Sub Button1_Click(sender As Object, e As EventArgs)
    Label1.Text = "Built at " & DateTime.Now.ToString()
End Sub

Sub listFruit_SelectedIndexChanged(sender As Object, e As EventArgs)
    Label1.Text = "You selected " & listFruit.SelectedItem.Text
End Sub
</script>

<head runat="server">
  <title>ASP.NET XHTML Page</title>
</head>

<body>
  <form id="Form1" runat="server">
    <div>
      <h1>ASP.NET Sample Page for XHTML</h1>
      <p>
      <asp:listbox runat="server" id="listFruit" AutoPostBack="true" 
          onselectedindexchanged="listFruit_SelectedIndexChanged">
         <asp:listitem>Apple</asp:listitem>
         <asp:listitem>Banana</asp:listitem>
         <asp:listitem>Orange</asp:listitem>
      </asp:listbox>
      </p>
      <asp:label runat="server" id="Label1" ForeColor="white" 
          BackColor="black" />
      <br />
      <asp:button runat="server" id="Button1" onclick="Button1_Click" 
          Text="Click me"/>
    </div>
  </form>
</body>
</html>
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
void Button1_Click(Object sender, EventArgs e)
{
    Label1.Text = "Built at " + DateTime.Now.ToString();
}
void listFruit_SelectedIndexChanged(Object sender, EventArgs e)
{
    Label1.Text = "You selected " + listFruit.SelectedItem.Text;
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>ASP.NET XHTML Page</title>
</head>
<body>
  <form id="Form1" runat="server">
    <div>
      <h1>ASP.NET Sample Page for XHTML</h1>
      <p>
      <asp:listbox runat="server" id="listFruit" AutoPostBack="true" 
          onselectedindexchanged="listFruit_SelectedIndexChanged">
         <asp:listitem>Apple</asp:listitem>
         <asp:listitem>Banana</asp:listitem>
         <asp:listitem>Orange</asp:listitem>
      </asp:listbox>
      </p>
      <asp:label runat="server" id="Label1" ForeColor="white" 
          BackColor="black" />
      <br />
      <asp:button runat="server" id="Button1" onclick="Button1_Click" 
          Text="Click me"/>
    </div>
  </form>
</body>
</html>

注意下列事项:

  • form 元素中不包含 action 属性,因为 action 属性会在呈现页面时添加。

  • Label 控件的格式设置属性将呈现为 style 属性。

  • 由于包含服务器脚本的 script 元素不会呈现在浏览器上,因此不需要 type 属性。

  • 页面在运行时呈现客户端脚本,以便启用 ListBox 控件的自动回发行为,但页面以一种 XHTML 兼容的方式来呈现脚本。

符合 XHTML 标准的静态文本和 HTML 元素

ASP.NET 不会更改您放在页面中的静态文本或非服务器 HTML 元素。例如,ASP.NET 网页可能包括 TextBox 和 Button 控件,以及在 <p></p> 标记内添加的一些静态文本。ASP.NET 可为 TextBox 和 Button 控件呈现 XHTML,但它不能更正在 <p></p> 标记之间发生的 XHTML 错误。如果创建了静态文本或 HTML 元素,请确保其符合 XHTML 标准。可以通过验证来检查页面,如下一节所述。

HTML 控件的未知属性将传递给呈现的控件输出,并且不会验证为有效的 XHTML 标记。例如,如果为 HtmlHead 控件指定了 ID 属性,将导致不符合 XHTML 1.0 Strict 标准的标记。若要对标记进行验证,请使用标记验证程序,例如“World Wide Web Consortium (W3C) Validation Markup Service”(万维网联合会 (W3C) 验证标记服务)

检查 ASP.NET 网页是否符合 XHTML 标准

创建 ASP.NET 网页之后,可能希望进行检查,以确定这些网页呈现的 XHTML 是否正确。如果页中包含 ASP.NET Web 服务器控件,则在编写页时将无法执行检查,因为这些控件只有在运行页时才会呈现 XHTML。

exc57y7e.alert_note(zh-cn,VS.90).gif说明:

有些可视化设计器(例如 Visual Studio)可以提供页标记的设计时 XHTML 验证功能。

若要检查页面的 XHTML 的有效性,必须使用一项运行页面并检查其输出的服务。典型的策略是将页面部署到一个公开的服务器上。该服务器可以是测试服务器,而不一定是成品服务器。但该服务器必须对 Internet 开放。然后,便可以使用一项验证服务,该项服务可以编程方式读取页面。

常用的服务是 W3C 标记验证服务,该服务由万维网联合会负责维护。若要使用此验证程序,请输入希望该项服务进行检查的页面的 URL。验证站点请求页面,并就其发现的所有错误生成报告。或者,您可以保存网页的源,然后将其作为一个文件提交给验证服务。有关此验证服务的更多信息,请参见 W3C 网站

如果您正在检查的页面中包含动态内容,或者用户可以在您的站点中对网页进行个性化处理,则一定要确保使用不同内容来测试页面,以确保页面中所有可能的内容都是有效的。在有些情况下,这可能很难实现,因为页面输出可能有太多的变化,以致无法进行有效的测试。

配置浏览器标记验证功能

在对页进行处理时,ASP.NET 会检查请求中有关当前浏览器的信息,并根据浏览器类型(用户代理字符串)来呈现适合于该浏览器的标记。有关更多信息,请参见 ASP.NET Web 服务器控件和浏览器功能

如果将 ASP.NET 网页提交到验证服务(例如 W3C 标记验证服务),ASP.NET 可能会呈现不符合 XHTML 标准的网页版本。这是因为验证服务不会将自己报告为 ASP.NET 可识别的浏览器类型(例如 Internet Explorer 或 Mozilla)。当 ASP.NET 无法识别浏览器类型时,它将默认呈现下级标记,后者中不包括符合 XHTML 标准的元素和属性,也不包括级联样式表样式这样的功能。

通过为验证服务的用户代理字符串创建浏览器定义,可以对应用程序进行配置,以向验证服务发送正确的符合 XHTML 标准的标记。例如,W3C 标记验证服务会报告一个以“W3C_Validator”开头的用户代理。若要为 W3C 验证程序创建浏览器定义,可以在应用程序的 App_Browsers 文件夹中创建一个 .browser 文件(可以采用任何名称来命名 .browser 文件),然后添加以下 browsers 元素。

<browsers>
  <browser id="W3C_Validator" parentID="default">
    <identification>
        <userAgent match="^W3C_Validator" />
    </identification>
    <capabilities>
      <capability name="browser"              value="W3C Validator" />
      <capability name="ecmaScriptVersion"    value="1.2" />
      <capability name="javascript"           value="true" />
      <capability name="supportsCss"          value="true" />
      <capability name="tables"               value="true" />
      <capability name="tagWriter" 
         value="System.Web.UI.HtmlTextWriter" />
      <capability name="w3cdomversion"        value="1.0" />
    </capabilities>
  </browser>
</browsers>

有关创建浏览器定义的更多信息,请参见浏览器定义文件架构(browsers 元素)

XHTML 一致性异常

虽然 ASP.NET 可以生成符合 XHTML 标准的标记,但在使用某些控件支持的可选功能时可能会产生不符合标准的标记。

exc57y7e.alert_note(zh-cn,VS.90).gif说明:

每个控件都会呈现其自身的标记。为了生成符合 XHTML 标准的输出,可能不能写入那些由其他方创建的自定义控件。如果使用自定义控件,请与控件供应商联系以确定其控件支持哪些标准。

Target 属性

可能会导致不符合标准的标记的控件示例为那些允许包括 target 属性来指定客户端行为的控件。

如果页中包含的控件带有 target 属性,则不会根据 XHTML 1.1 对页进行验证。如果对您来说创建完全符合 XHTML 1.1 标准的页非常重要,则应避免使用 target 属性等选项,因为这样会产生不符合标准的标记。

Select 元素

DropDownListListBox 控件可用于创建单项或多项选择。DropDownListListBox 控件均可呈现 HTML select 元素。如果 DropDownListListBox 控件没有至少包含一个 ListItem 控件,则呈现的 select 元素将不包含任何子 option 元素,并且不会对照 XHTML 1.1 进行验证。

请参见

任务

如何:在 ASP.NET 网站中配置 XHTML 呈现