我继承了 System.Web.UI.HtmlTextWriter 在 ASP.NET 应用程序中执行一些自定义的 HTML 呈现。这是使用以下内容在我的 Web.config 文件中配置的:
<browserCaps>
tagwriter="MyAssembly.CustomHtmlTextWriter, MyAssembly"
</browserCaps>
这对于常规页面请求正常工作,调用 OnTagRender 等重写方法并将自定义 HTML 发送到浏览器。
但是,当使用 UpdatePanel 执行异步回发时,永远不会调用此代码,并且 HTML 会在没有我的自定义修改的情况下到达浏览器。我是否缺少一些将为 AJAX 请求加载自定义 HtmlTextWriter 的配置?
最佳答案
首先,我可以向您保证,您的自定义 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 架构应该可以完成工作。
例如,假设我想将所有文本框和标签替换为仅包含其 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% 正常工作。
关于asp.net - 如何为 ASP.NET AJAX UpdatePanel 请求重写 HtmlTextWriter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14726625/