不同的浏览器所支持的功能大相径庭,要创建一个兼容所有浏览器,又提供最好的用户体验的应用程序是一项很大的挑战。ASP.NET 提供了一些新的功能来帮助你为不同的设备编写正确的标记类型。
HtmlTextWriter
ASP.NET 对客户端的标记类型作了一个大致的区分,因此有的客户端见到 HTML 3.2,有的见到 HTML 4.0,而有的见到 XHTML 1.1,你甚至不会意识到这种区分的发生。
所有这些的发生都是通过 HtmlTextWriter 类完成的。这个类有几个派生类。HtmlTextWriter 用于输出 HTML 4.0 标记,但它的派生类却大为不同:Html32TextWriter 能够输出 HTML 3.2 标记,而 XhtmlTextWriter 输出 XHTML 1.1。
因为所有这些类都从 HtmlTextWriter 派生,所以你可以在自己的呈现代码中自由使用 HtmlTextWriter 方法中相同的基本集合。然而,这些方法的实现却大都不同,因此,根据你使用的对象不同,输出可能也不同。
例如,如果使用以下呈现代码:
output.RenderBeginTag(HtmlTextWriterTag.Div);
认为结果如下:
<div>
但是,你用 Html32TextWriter 时将会看到这样的结果(假设 Html32TextWriter.ShouldPerformDivTableSubstitution 被设置为 true):
<table cellpadding=”0” cellspacing=”0” border=”0” width=”100%”><tr><td>
另一方面,如果使用下面这段代码,不管目标设备的能力如何,你的呈现输出将是完全不灵活的和永远不变的:
output.Write(“<div>”);
相似的,如果你从 WebControl 派生类来得到样式属性的自动支持,不同的呈现器会有不同的实现。
这里总的经验是:
避免编写原始的 HTML(使用 Write() 方法),而应在任何可能的地方使用高级方法(如 RenderBeginTag(),RenderEndTag() 等),这样,控件会有更强的灵活性。ASP.NET 将基于请求页面的浏览器的能力,创建和传入正确的 HtmlTextWriter ,HTML 标记能自适应。
这个问题不像过去那样重要了,因为现在常用的浏览器几乎都支持 XHTML 。不过,这仍然是一个很好的设计,因为它确保了当 ASP.NET 被更新以支持那些具有不同支持范围的浏览器后,你的代码还能够完美的工作。
浏览器检测
ASP.NET 是怎么判断哪一种文本编写器适用于某一个特定的客户端呢?
这完全取决于客户端发起请求时提供的用户代理字符串。ASP.NET 尝试将这个字符串与一个包含所有已知浏览器的大型目录做比对。
你可以在下面的路径找到这个目录:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Config\Browsers
在那里,有许多 .browser 文件。每一个都是 XML 文件,每个文件将用户代理字符串映射到一组功能和一个文本编辑器。
每个 .browser 文件拥有如下基本结构:
<browser id="IE" parentID="Mozilla">
<identification>
<userAgent match="MSIE (?'version'(?'major'\d+)(\.(?'minor'\d+)?)(?'letters'\w*))(?'extra'[^)]*)" />
<userAgent nonMatch="IEMobile" />
</identification>
<capture>
<userAgent match="Trident/(?'layoutVersion'\d+)" />
</capture>
<capabilities>
<capability name="browser" value="IE" />
<capability name="layoutEngine" value="Trident" />
<capability name="layoutEngineVersion" value="${layoutVersion}" />
<capability name="extra" value="${extra}" />
...
</capabilities>
</browser>
...
</browsers>