我继承了System.Web.UI.HtmlTextWriter,以便在ASP.NET应用程序中自定义呈现HTML.这是在我的Web.config文件中使用以下内容进行配置的:
<browserCaps>
tagwriter="MyAssembly.CustomHtmlTextWriter, MyAssembly"
</browserCaps>这对于常规的页面请求是正确的,调用被覆盖的方法,例如OnTagRender,并且定制的超文本标记语言被发送到浏览器。
但是,当使用UpdatePanel执行异步回发时,此代码永远不会被调用,并且在未进行自定义修改的情况下,HTML会到达浏览器中。我是否遗漏了为AJAX请求加载自定义HtmlTextWriter的配置?
发布于 2013-02-09 04:11:38
首先,我可以向您保证,您的自定义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,但是您通常用来更改标记的方法都没有被调用)。
在这一点上,值得注意的是,.NET 2.0中不推荐使用browserCaps标记,因此似乎不支持您的用例也就不足为奇了。根据您到底想要做什么,我认为ControlAdapter架构应该能完成这项工作。
例如,假设我希望将所有TextBoxes和标签替换为仅包含其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 "Default“将在所有浏览器上执行此操作。现在,当需要呈现Label或TextBox web控件时,CustomControlAdapter会处理它。上面的代码在我的示例应用程序中进行了测试,即使使用AJAX也能很好地工作。在您的情况下,我猜您只需要在上面的Adapters.browser文件中添加更多的控件类型,并且您应该是100%的业务人员。
https://stackoverflow.com/questions/14726625
复制相似问题