如何在输出之前修改整个 ASP.NET 页面内容?

Posted

技术标签:

【中文标题】如何在输出之前修改整个 ASP.NET 页面内容?【英文标题】:How can I modify the entire ASP.NET page content right before it's output? 【发布时间】:2010-12-07 11:48:40 【问题描述】:

我有一个页面,上面有一堆用户控件。我希望能够直接在将在我的代码中替换的内容中包含“宏”或“占位符”。这应该不重要,但我使用 Ektron 作为我的 CMS。

在将整个呈现的页面内容发送到客户端之前,是否有任何页面事件可以挂钩以对整个呈现的页面内容进行字符串替换?

更新

这是我目前用来完成此操作的代码:

protected override void Render(htmlTextWriter writer)

    string content = string.Empty;

    using (var stringWriter = new StringWriter())
    using (var htmlWriter = new HtmlTextWriter(stringWriter))
    
        // render the current page content to our temp writer
        base.Render(htmlWriter);
        htmlWriter.Close();

        // get the content
        content = stringWriter.ToString();
    

    // replace our placeholders
    string newContent = content.Replace("$placeholder1$", "placeholder1 data").Replace("$placeholder2$", "placeholder2 data");

    // write the new html to the page
    writer.Write(newContent);

【问题讨论】:

【参考方案1】:

您是否查看过生命周期中的 PreRender 事件?

在此事件发生之前:

• Page 对象调用 EnsureChildControls 每个控件和页面。

• 每个 DataSourceID 的数据绑定控件 设置属性调用其 DataBind 方法。

• PreRender 事件发生 对于页面上的每个控件。 使用 事件对 页面或其控件的内容

我相信这是你可以做这种事情的最后一个地方。下一个事件是 SaveStateComplete,根据文档,它具有以下行为:

在此事件发生之前,已为页面保存了 ViewState 和所有控件。 任何更改 此时的页面或控件 将被忽略。 使用此事件 执行需要视图状态的任务 得救,但不使任何 对控件的更改。

引用来源:https://www.c-sharpcorner.com/UploadFile/8911c4/page-life-cycle-with-examples-in-Asp-Net/

【讨论】:

【参考方案2】:

您可以使用两种方法:

    这类似于接受的 回答。但我会推荐 覆盖中的渲染方法 BasePage 并导出你所有的 模板由此而来。

    使用 HttpModule 或 Global.asax 和 将Filter 附加到响应中 目的。对我来说,这让更多 美感因为“滤镜” 财产应该可以帮助你 过滤正好是的输出 你想要什么!

【讨论】:

感谢您的回答。为努力投票! BasePage 并不是一个真正不同的解决方案,但更多的是对已接受的解决方案的补充。但好主意。我认为创建一个所有页面都派生自的 BasePage 类总是一个好主意。或者可能是 2-3 个,具体取决于您拥有的页面类型。至于 HttpModule 和过滤器,那就太好了!同样,类似于公认的解决方案,但替换的逻辑将从页面中提取出来。如果您在多个地方进行替换,那就太好了!不错!【参考方案3】:

您是否尝试过覆盖渲染方法?

protected override void Render(HtmlTextWriter writer)

   StringBuilder htmlString = new StringBuilder(); // this will hold the string
   StringWriter stringWriter = new StringWriter(htmlString);
   HtmlTextWriter tmpWriter = new HtmlTextWriter(stringWriter);
   Page.Render(tmpWriter);
   writer.Flush();

   writer.Write(DoReplaceLogic(htmlString.ToString()););

【讨论】:

是的,这是正确的地方,但是否可以(并且明智地)重置并读取流? 您永远不会“重置”流,因为它尚未发送。我不确定它是否明智,不,我只是回答了这个问题,哈哈 我现在正在使用这种方法,但会等待接受答案,看看是否有更好的解决方案。基本上我...让页面写入临时缓冲区。修改缓冲区。用修改后的缓冲区替换原来的缓冲区。【参考方案4】:

听起来您可能希望在页面中包含 HTML 文字,然后您可以在 Page_Load 事件中简单地将它们替换为适当的内容。

这将要求您编写 HTML 代码,而不是一些简单的文本,但听起来您可能会在其中注入自己的 javascript 代码或类似代码,这将非常适合。

【讨论】:

【参考方案5】:

想到的简单答案是使用 asp:Literal 控件作为“占位符”。您可以在页面加载期间设置它们的内容,或者您​​可以挂钩到 PreRender 事件然后设置它们。

【讨论】:

不幸的是,我不能这样做,因为这些“占位符”将在用户控件中呈现的内容中,我无法触摸。所以当它到达我的时候,我唯一希望做的就是查看渲染的内容。 对不起,我错过了“用户控制”,我的错。用户控件也有 PreRender 事件。您应该能够将公共属性放在页面可以设置的用户控件上,然后让用户控件进行替换。

以上是关于如何在输出之前修改整个 ASP.NET 页面内容?的主要内容,如果未能解决你的问题,请参考以下文章

请问ASP.NET中当点击某个控件时(如Button)不想进行整个页面的刷新怎样设置?

ASP.net如何实现数据的查询,删除,修改,编辑!

如何提高ASP.NET页面载入速度的方法

ASP.Net Core:如何获取无效 ModelState 值的键?

如何从整个页面asp.net c#中删除类名

带有 ASP.NET WebMethod 的 Jquery AJAX 返回整个页面