According to MSDN, the ScriptManager.RegisterStartupScript
method, (Page, Type, String, String, Boolean)
overload, registers a script for "every asynchronous postback with the ScriptManager control and adds the script block to the page." Yet, that does not seem to be the behavior. Instead, the script executes only once, on the next page or UpdatePanel render following the call of the method. It does not even need to be within an asynchronous postback: a regular postback, or initial GET will also cause the script to execute.
This must be an error in the documentation. What do you think? Run the sample below, and note that after registering the startup script, the alert is displayed, but then when clicking the other dummy button to cause another postback, the alert is not displayed, because the script is not executed. And yet, you can click the register button again, and the alert will again be displayed, showing that the behavior is not caused by some sort of suppression of duplicate script keys.
<%@ Page Language="C#" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html>
<head runat="server">
<script type="text/javascript">
function MyFunction() { alert("MyFunction"); }
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel ID="upTest" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="btnRegisterStartupScript" text="RegisterStartupScript" OnClick="btnRegisterStartupScript_Click" runat="server"/>
<asp:Button ID="btnDummyPostback" Text="Dummy Postback" runat="server" />
<%=DateTime.Now%>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
<script runat="server">
protected void btnRegisterStartupScript_Click(object oSender, EventArgs e) {
ScriptManager.RegisterStartupScript(this, this.GetType(), "MyFunction", "MyFunction();", addScriptTags: true);
}
</script>
Personally, I don't mind this behavior, as there needs to be a method that allows developers to run a script only on the current async postback. But I think the documentation should be more accurate. The documented behavior can be achieved, but only if you call ScriptManager.RegisterStartupScript(this, this.GetType(), "MyFunction", "Sys.Application.add_load(function() { MyFunction(); });", addScriptTags: true);
which will use the client-side framework to register the script within the anonymous function block.