65.9K
CodeProject 正在变化。 阅读更多。
Home

一个 C# 类,可使您的 ASP.NET 页面符合 XHTML 标准

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (23投票s)

2004年9月27日

4分钟阅读

viewsIcon

287642

downloadIcon

1234

一个 C# 类,可使您的 ASP.NET 页面符合 XHTML 标准。

最新更新 (V1.1)

修复了 ConvertToLowerCase 方法中无法处理带属性的标签的 bug。

引言

本文介绍了一个简单的类,可用于调整 ASP.NET 生成的 HTML 代码,使其符合 XHTML 文档的标准。

符合 XHTML 标准的文档是使用 W3C 标记验证服务 (参见 http://validator.w3.org) 成功测试过的文档。这项免费服务会检查 XHTML 文档是否符合 W3C 的建议。这不仅有助于确保您的网站能够被任何符合 W3C 标准的浏览器正确处理,而且这种合规性也可能是客户的特定要求。

问题所在

问题是,如果您尝试使用 ASP.NET 创建 XHTML 文档,您可能会失败,因为 ASP.NET 引擎生成的代码不是 XHTML。

只需创建一个简单的 ASPX 页面,然后运行 W3C 验证器。以下是您会发现的错误列表

大写标签

XHTML 全部小写且区分大小写。对于 XHTML 验证器来说,像 HTMLHEAD 这样的标签是未定义的。对于这类问题,您可以简单地手动编辑 HTML,直接使用 Visual Studio 编辑器。不幸的是,每次您在页面上添加新控件,并在设计视图和 HTML 视图之间来回切换时,Visual Studio 编辑器都会将 HTMLHEAD 标签全部大写。

自闭合标签

在 XHTML (以及 XML) 中,所有标签都必须有相应的闭合标签,或者必须是自闭合标签。像 <br><link href="style.css" rel="stylesheet"> 这样的标签不符合 XHTML 标准。您应该使用 <br /><link href="style.css" rel="stylesheet" />

已弃用的属性

一些有效的 HTML 属性已被 XHTML 弃用。例如,name 属性被 id 替代。如果您查看 ASP.NET 的 HTML 代码,您会看到以下脚本 (该脚本实际上用于处理 ASP.NET 回发机制)。

<form name="Form1" method="post" action="Index.aspx" id="Form1">
<input type="hidden" name="__EVENTTARGET" value="" ID="Hidden1"/>
<input type="hidden" name="__EVENTARGUMENT" value="" ID="Hidden2"/>
<input type="hidden" name="__VIEWSTATE" 
  value="ReuDDhCfGkeYOyM6Eg==" ID="Hidden3"/>

<script language="javascript">
       
function __doPostBack(eventTarget, eventArgument) {
   var theform;
   if (window.navigator.appName.toLowerCase().indexOf("netscape") > -1
   {
      theform = document.forms["Form1"];
   }
   else {
      theform = document.Form1;
   }
   theform.__EVENTTARGET.value = eventTarget.split("$").join(":");
   theform.__EVENTARGUMENT.value = eventArgument;
   theform.submit();
}
</script>

为了使此代码符合 XHTML 标准,需要删除 form 标签的 name 属性。

请注意,此代码仅在创建页面时生成。您无法在设计时更改它。

必需的属性

上面的脚本还有另一个问题。在 script 标签中,缺少 type="text/javascript" 属性。根据 XHTML 规范,此属性是必需的。

放置不当的属性

仍然考虑 Form1 的内容,隐藏的 input 标签未正确放置。事实上,根据 XHTML 规范,input 标签必须包含在以下标签之一中:“p”、“h1”、“h2”、“h3”、“h4”、“h5”、“h6”、“div”、“pre”、“address”、“fieldset”、“ins”、“del”。

解决方案

一个可能的解决方案是拦截 HTML 代码,然后在将其发送到客户端 Web 浏览器之前进行必要的更正。

XHTMLPage 类

XHTMLPage 类继承自 System.Web.UI.Page 类,并重写了 Render 方法。

protected override void Render(HtmlTextWriter output) 
{
   StringWriter w; 
   w = new StringWriter();
            
   HtmlTextWriter myoutput = new HtmlTextWriter(w);
   base.Render(myoutput);

   myoutput.Close();

   m_sXHTML = w.GetStringBuilder().ToString();
            
   ReplaceDocType();

   switch (m_XHTMLFormat)
   {
      case _XHTMLFormat.XHTML10_Strict:
         ConvertToXHTMLStrict();
         break;
      case _XHTMLFormat.XHTML10_Transitional:
         ConvertToXHTMLTransactional();            
         break;
   }
            
   output.Write(m_sXHTML);
}

XHTMPage::Render 方法中,首先调用基类方法 base.Render,使用一个本地创建的新 HtmlTextWriter 对象。HtmlTextWriter 基于一个底层的 StringWriter 对象;这样,ASP.NET 生成的 HTML 代码就可以放在 m_sXHTML 字符串中,然后进行处理。

ConvertToXHTML… 方法负责将无效的 XHMTL 部分替换为等效的 XHTML 代码。

使您的页面符合 XHTML 标准

为了使任何 ASP.NET 页面成为符合 XHTML 标准的页面,您只需要继承自 XHTMLPage 而不是 System.Web.UI.Page

public class Index : XHTMLPage
//public class Index : System.Web.UI.Page

XHTMLPage 可以使用 XHTMLFormat 属性进行配置;此属性可以设置为 StrictTransitional (默认值),以便使页面符合 XHTML Strict 或 SHTML Transitional 规范。

base.XHTMLFormat = XHTMLPage._XHTMLFormat.XHTML10_Strict;

结论

我在这里介绍了一个在使用 ASP.NET 获取符合 XHTML 标准的页面时可能遇到的问题。这个问题可能在下一版本的 Visual Studio 中得到解决,但在此之前,我提供了一个可能对您有用的简单解决方案。

在附带的示例代码中,我没有过多关注性能,但解析 ASP.NET 生成的 HTML 显然需要一些时间。

致谢

  • sebmafate 在扩展和修复类功能方面给予了我帮助。

历史

2004年11月4日

  • 修复了 ConvertToLowerCase 方法中无法处理带属性的标签的 bug。

2004年10月13日

  • 自动将所有标签和属性名转换为小写。
  • 添加了对 XHTML Frameset 规范的支持。
  • 添加了对编码和语言 XML 属性的支持。
  • 添加了对 CDATA 属性的支持。

2004年9月27日

  • First version.
© . All rights reserved.