首先,我模擬一個“事發現場”,由此開始解決問題:一般來說,在所有的頁面中可能需要統一的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;
}
至此,任務結束。