MSDN documentation error? ScriptManager.RegisterStartupScript does not execute for every asynchronous postback

StackOverflow https://stackoverflow.com/questions/20203044

Вопрос

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.

Это было полезно?

Решение

After reading the documentation for the other overload of this method, RegisterStartupScript(Control, Type, String, String, Boolean), I think I have the answer: The words "for every asynchronous postback" are intended as a contrast to the behavior of this overload:

Startup script blocks that are registered by using this method are sent to the page only when the control that is registering the block is inside an UpdatePanel control that is being updated.

In other words, the first overload registers the startup script only when the specified control is within an UpdatePanel being updated, whereas the second overload registers the startup script regardless, every time it called. Somehow this gave birth to the phrasing "for every asynchronous postback", which is not accurate. A better way to phrase it would be "Registers a startup script block with the ScriptManager control and adds the script block to the page. The script block is executed only once, when the page or UpdatePanel is rendered."

I have submitted a bug report to Connect, and I will mark this answer accepted if they agree with me.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top