2017-10-28 130 views
0

我有一個能夠在每個頁面上都有動態客戶特定文本替換的要求。例如,我可以將「{CarMake}」放在一個頁面的任何位置,並且它會將我們的福特客戶的「{CarMake}」更改爲「Ford」,將豐田等的「Toyota」更改爲我們正在做的Page.Render函數,它將在輸出到客戶端之前對呈現的html進行替換。PageRequestManagerParserErrorException - 具有自定義Page.Render的UpdatePanel

自定義的Page.Render與Response Filter基本相同,我已經閱讀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,但沒有效果。

+0

如果響應包含正確替換的文本,您是否需要執行sb.Replace? – wazz

+0

@wazz sb.Replace是什麼在做文本替換。在sb.Replace調用之前,呈現的HTML輸出仍然包含{CarMake} – emkayultra

+0

啊。它包含正確替換的文本,但在代碼運行後。 :\ – wazz

回答

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); 
     } 
    } 
} 
+0

這個信息真的很有用 - 我不知道SaveViewState在Render之前被調用。然而,我仍然處於虧損狀態:你究竟在Page_PreRenderComplete中修改了什麼?我挖掘了Page的源代碼,並沒有看到我可以可靠地用來引用Page的HTML輸出的屬性。除非你直接操縱Page.Controls? – emkayultra

+0

@emkayultra請參閱更新。 ;) –

+0

我想這將會是你說的,而這正是我最終做的。我對導航Page的控制層次結構與後處理呈現的HTML字符串的性能有點擔心,但這是必須要做的。謝謝! – emkayultra

相關問題