ajax|asp.net|建立|問題|頁面
昨日下午,IM上遇到菌哥,被問到為什麼安裝ASP.NET AJAX RC之後,某些頁面總是在建立UpdateProgress時出現指令碼錯誤。當時給了一個不太好的解決方案,剛才簡單看了一下System.Web.Extensions.dll中的相關實現,得出了一個更好的解決方案,在這裡簡單地說一下。
首先,我類比一個“事發現場”,由此開始解決問題:一般來說,在所有的頁面中可能需要統一的Updating Animation,於是可能會將一個UpdateProgress連同ScriptManager放在MasterPage中,如下:
Site.master
<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">
</asp:ScriptManager>
<asp:ContentPlaceHolder id="Main" runat="server"></asp:ContentPlaceHolder>
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
Hello World!
</ProgressTemplate>
</asp:UpdateProgress>
如果直接以此產生一個頁面,並隨意加上一個UpdatePanel:
Default.aspx
<asp:Content ID="Content1" ContentPlaceHolderID="Main" Runat="Server">
<asp:UpdatePanel runat="server">
<ContentTemplate>
...
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
此時產生的HTML為:
HTML
...
<form>
...
<script src="/AjaxEnabledWebSite/WebResource.axd?..."
type="text/javascript"></script>
<!-- MicrosoftAjax.js -->
<script src="/AjaxEnabledWebSite/ScriptResource.axd?..."
type="text/javascript"></script>
<!-- MicrosoftAjaxWebForms.js -->
<script src="/AjaxEnabledWebSite/ScriptResource.axd?..."
type="text/javascript"></script>
...
<script type="text/javascript">
<!--
Sys.Application.initialize();
Sys.Application.add_init(function() {
$create(
Sys.UI._UpdateProgress,
{"associatedUpdatePanelId":null,
"displayAfter":500,
"dynamicLayout":true},
null,
null,
$get("ctl00_UpdateProgress1"));
});
// -->
</script>
...
</form>
...
請注意此時的UpdateProgress以一個Sys.UI.Control的形式使用$create被建立,而Sys.UI._UpdateProgress(看來ASP.NET AJAX不希望我們直接使用這個類)是在MicrosoftAjaxWebForms.js檔案裡被引入。
於是問題就出現了,如果頁面中沒有UpdatePanel,那麼MicrosoftAjaxWebForms.js檔案不會被引入,而那句$create還在!這就導致了JavaScript錯誤的發生。當時我提供的方法是:那麼就在Site.master裡強制加上一個UpdatePanel吧。如下:
強制UpdatePanel
<asp:UpdatePanel runat="server" UpdateMode="Conditional" ID="UP1">
<ContentTemplate></ContentTemplate>
</asp:UpdatePanel>
這裡把UpdateMode設為了Conditional,也就是說,這裡的UpdatePanel永遠不會被更新,它的作用只是“強迫”MicrosoftAjaxWebForms.js檔案被引入。不過這不是個好的解決方案。
如果要解決這個問題,不要讓$create語句出現不就可以了嗎?在查看過代碼以後,發現$create語句只會在ScriptManager的EnablePartialRendering屬性為True的情況下出現,那麼我們就把ScriptManager的這個屬性暴露出去吧。我們可以修改一下Site.master.cs中Site類的代碼,把它增加一個屬性:
Site.master.cs
public bool EnablePartialRendering
{
get
{
return this.ScriptManager1.EnablePartialRendering;
}
set
{
this.ScriptManager1.EnablePartialRendering = value;
}
}
然後在頁面裡把MasterPage的EnablePartialRendering屬性設為False即可。需要注意的是只有Init階段才能設定ScriptManager的EnablePartialRendering屬性。如下:
Default.aspx.cs
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
(this.Master as Site).EnablePartialRendering = false;
}
至此,任務結束。
http://www.cnblogs.com/JeffreyZhao/archive/2006/12/20/597416.html