PageRequestManagerParserErrorException - 具有自定义 Page.Render 的 UpdatePanel
PageRequestManagerParserErrorException - UpdatePanel with custom Page.Render
我需要能够在每个页面上进行动态的客户特定文本替换。例如,我可以将“{CarMake}”放在页面的任何位置,它会将“{CarMake}”更改为我们福特客户的 "Ford",丰田客户的 "Toyota",等等。我们正在做这是一个自定义 Page.Render 函数,它将在输出到客户端之前对呈现的 html 进行替换。
自定义 Page.Render 与响应过滤器本质上是相同的想法,我已经阅读了 Eilon Lipton's fantastic explanation of this error,但我仍然对为什么在我的特定情况下这是一个问题感到困惑。
.ASPX 页面标记在 UpdatePanel 中包含:
<p>{CarMake}</p>
然后加载页面的渲染HTML包含:
<p>Ford</p>
然后,当 UpdatePanel 执行部分回发时,我收到上述 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,但没有任何效果。
我想您的替换模板 {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);
}
}
}
我需要能够在每个页面上进行动态的客户特定文本替换。例如,我可以将“{CarMake}”放在页面的任何位置,它会将“{CarMake}”更改为我们福特客户的 "Ford",丰田客户的 "Toyota",等等。我们正在做这是一个自定义 Page.Render 函数,它将在输出到客户端之前对呈现的 html 进行替换。
自定义 Page.Render 与响应过滤器本质上是相同的想法,我已经阅读了 Eilon Lipton's fantastic explanation of this error,但我仍然对为什么在我的特定情况下这是一个问题感到困惑。
.ASPX 页面标记在 UpdatePanel 中包含:
<p>{CarMake}</p>
然后加载页面的渲染HTML包含:
<p>Ford</p>
然后,当 UpdatePanel 执行部分回发时,我收到上述 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,但没有任何效果。
我想您的替换模板 {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);
}
}
}