Search code examples
asp.netwebformsupdatepanel

ASP.NET UpdatePanel - inline variable


I have a server-side variable which is assigned a value in PreRender. For the sake of simplicity, let's imagine I'm doing this:

    protected string test;
    protected void Page_PreRender(object sender, EventArgs e)
    {
        test = Guid.NewGuid().ToString();
    }

In my markup, the variable is then referred to within an UpdatePanel, like so:

    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:Button ID="Button1" runat="server" Text="Perform postback" />
            <script type="text/javascript">
                Sys.Application.add_load(function () {
                    alert('<%=test%>');
                });
            </script>
        </ContentTemplate>
    </asp:UpdatePanel>

On first load of the page, the JavaScript alert function gives me a random value, as expected. However, on any subsequent postback, the original value of the Guid is retained.

Can anybody explain why this is so, and offer a solution? I'm fairly sure I can achieve the required behaviour by putting the value of 'test' in a hidden field, for example, but ideally I wouldn't have to sink to those depths. Unfortunately replacing the UpdatePanel with something lighter isn't really an option.


Solution

  • I've found a solution to this, and nor is it quite as dirty as I'd feared. I declare a JS variable outside of the function:

        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Button ID="Button1" runat="server" Text="Perform postback" />
                <script type="text/javascript">
                    var test;
    
                    Sys.Application.add_load(function () {
                        alert(test);
                    });
                </script>
            </ContentTemplate>
        </asp:UpdatePanel>
    

    In my code-behind, I assign the JS variable a value in the Sys.Application.add_init method, like so:

        protected void Page_PreRender(object sender, EventArgs e)
        {
            ScriptManager.RegisterStartupScript(this, typeof(UpdatePanelTest), "startupScripts", "Sys.Application.add_init(function() {test='" + Guid.NewGuid().ToString() + "';});", true);
        }
    

    Voilà, a different Guid is then displayed on first load and every postback.