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






4.87/5 (23投票s)
2004年9月27日
4分钟阅读

287642

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 验证器来说,像 HTML
或 HEAD
这样的标签是未定义的。对于这类问题,您可以简单地手动编辑 HTML,直接使用 Visual Studio 编辑器。不幸的是,每次您在页面上添加新控件,并在设计视图和 HTML 视图之间来回切换时,Visual Studio 编辑器都会将 HTML
和 HEAD
标签全部大写。
自闭合标签
在 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
属性进行配置;此属性可以设置为 Strict
或 Transitional
(默认值),以便使页面符合 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.