我要求能够在每个页面上进行动态的客户特定文本替换。例如,我可以将“{CarMake}”放在页面的任何位置,它会为我们的福特客户将“{CarMake}”改为“Ford”,为丰田等改为“丰田”。我们这样做是为了定制Page.Render函数,它将在输出到客户端之前对渲染的html进行替换。
自定义Page.Render本质上与响应过滤器的想法相同,我已经阅读了Eilon Lipton's fantastic explanation of this error,但我仍然对为什么在我的特定情况下这是一个问题感到困惑。
.ASPX页面标记包含在UpdatePanel中:
<p>{CarMake}</p>
然后,已加载页面的呈现HTML包含:
<p>Ford</p>
然后,当UpdatePanel执行Partial PostBack时,我得到了UpdatePanel响应的上述解析错误,该错误似乎包含正确替换的文本(就像HTML的初始呈现一样):
"1|#||4|2325|updatePanel|UpdatePanelCars|...<p>Ford</p>..."
那么,如果呈现的HTML完全相同,为什么会导致问题呢?客户端如何解析甚至检测到差异?
作为参考,进行替换的代码是:
class TemplatedPage: System.Web.UI.Page
{
...
protected override void Render(HtmlTextWriter writer)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter hWriter = new HtmlTextWriter(sw);
base.Render(hWriter); //obtain full html markup, still containing {} at this point
sb.Replace("{CarMake}", "Ford");
//other Replacements...
string alteredPageContents = sb.ToString();
writer.Write(alteredPageContents);
}
}
我尝试将EnableEventValidation设置为false,但这没有效果。
答案 0 :(得分:1)
我猜您的替换模板{something}
位于服务器端控件内,如<asp:Literal runat="server">{something}</asp:Literal>
。生命周期中的aspx页面经历了许多阶段,render
非常接近结束。在运行render
之前,页面会保存ViewState
,以保留所有控件的状态(内容),服务器控件内容中的任何更改都会导致post
ed请求不匹配并保存ViewState
。
您可以修改页面内容的最新时刻是page_PreRenderComplete
事件处理程序
当然,如果页面没有post
(全部或部分),则无关紧要
事实上,我在许多(所有)页面中使用非常相似的代码,但我只重新排序控件渲染(将script
放到底部,依此类推)。 render
内的替换导致错误,我在Page_PreRenderComplete
内使用了一些解决方法。
更新回复评论
在Page_PreRenderComplete
中,您可以处理页面树以进行替换。像这样:
void Page_PreRenderComplete(object sender,EventArgs e)
{
ProcessPageTree((Control)sender); //sender is Page which inherit from Control
}
void ProcessPageTree(Control control) //All server side controls inherit from abstract Control
{
if(control is HyperLink)
{
var hl = control as HyperLink;
hl.Text = hl.Text.Replace("{{something}}", "something new");
}
else if(control is Literal)
{
var ltr = control as Literal;
ltr.Text = ltr.Text.Replace("{{some}}", "something another");
}
if (control.HasControls())
{
foreach(Control c in control.Controls)
{
ProcessPageTree(c);
}
}
}