首先,我可以向您保证您的自定义 HTMLTextWriter 被正确调用,并且您在配置中没有做错任何事情。
使用您的 web.config 部分,我编写了一个测试应用程序,并在该行包含以下断点var cap = ...
:
protected void UpdatePanel1_Load(object sender, EventArgs e)
{
var cap = Request.Browser.TagWriter;
}
在初始 HTTP GET 和 AJAX 回发中,断点被命中,我可以看到所使用的 TagWriter 实际上是 CustomHtmlTextWriter。另外,我可以在 CustomHtmlTextWriter 构造函数上设置一个断点,并且这个断点在回发时被命中。
我还确认,即使您在回发中添加了一个全新的控件,即使调用了 CustomHtmlTextWriter 构造函数,OnTagRender、OnAttributeRender 和其他事件也不会触发。
此外,不会调用 RenderBefore...() 和 RenderAfter...() 方法。
所以这回答了你的问题“我在我的配置中做错了什么吗?”:不,你没有。您的自定义 HtmlTextWriter 被实例化和引用,但没有调用任何有用的方法(调用了 BeginRender,但没有调用通常用于更改标签的方法)。
在这一点上,值得注意的是 browserCaps 标记在 .NET 2.0 中已被弃用,因此您的用例似乎不受支持也许并不奇怪。根据您到底要做什么,我认为 ControlAdapter 架构应该可以完成工作。
例如,假设我想将所有 TextBoxes 和 Labels 替换为仅包含其 ID 的跨度,并在初始 GET 和 AJAX 回发上进行这项工作。当然,您的示例会更复杂,但希望这种简化会给您带来想法。
我需要做的就是创建一个可以作用于任何 Web 控件的 ControlAdapter:
public class CustomControlAdapter : WebControlAdapter
{
protected override void RenderBeginTag(HtmlTextWriter writer)
{
writer.WriteLine();
writer.WriteBeginTag("span");
writer.Write(HtmlTextWriter.TagRightChar);
}
protected override void RenderEndTag(HtmlTextWriter writer)
{
writer.WriteEndTag("/span");
writer.WriteLine();
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.WriteLine(Control.ID);
}
}
然后,我将它连接到我感兴趣的控件类型。为此,我在 App_Browsers 文件夹中创建了一个 Adapters.browser 文件,并包含以下配置:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter
controlType="System.Web.UI.WebControls.Label"
adapterType="WebApplication1.CustomControlAdapter"
/>
<adapter
controlType="System.Web.UI.WebControls.TextBox"
adapterType="WebApplication1.CustomControlAdapter"
/>
</controlAdapters>
</browser>
</browsers>
请注意,我的“默认”浏览器 refID 将在所有浏览器上运行。现在,当需要呈现 Label 或 TextBox Web 控件时,CustomControlAdapter 会处理它。上面的代码在我的示例应用程序中进行了测试,即使使用 AJAX 也能完美运行。在您的情况下,我猜您只需要在上面的 Adapters.browser 文件中添加更多控件类型,您就应该 100% 投入业务。