asp.net - 如何为 ASP.NET AJAX UpdatePanel 请求重写 HtmlTextWriter?

标签 asp.net asp.net-ajax

我继承了 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/

相关文章:

javascript - ASP.NET 表单根据另一个字段中的部分显示表单字段

html - IE 的菜单 CSS 问题

c# - 为什么 Ajax.BeginForm 在 Chrome 中不起作用?

c# - 从更新面板回发后调用 javascript 代码

javascript - 在页面加载时将所有 'disabled' 属性更改为 'readonly' 属性?

asp.net - 是否可以在 Windows 8 上安装 IIS 7.5 或 7

asp.net - 您能推荐一个 .net 模板引擎吗?

c# - 选中一个框时填充一个框,如何处理?

javascript - 如何检查页面是否在 ASP.NET AJAX 上的保留函数 pageLoad 中回发

jquery - 将所选内容应用于 jtable 多选下拉列表