Search code examples
c#asp.netupdatepanelpostbackcode-behind

Button in UpdatePanel triggers event, but the page doesn't update


Here's the markup:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <div class="well well-large">
            <form class="navbar-form pull-left">
                <asp:FileUpload ID="test" runat="server" CssClass="input-small" />
                <br />
                <asp:Button ID="btnUpload" runat="server" Text="Upload" CssClass="btn" OnClick="btnUpload_Click" />
            </form>
        </div>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="btnUpload" EventName="Click" />
    </Triggers>
</asp:UpdatePanel>

<asp:Panel runat="server" ID="panAlert" Visible="false">
    <div class="alert alert-success" id="divAlert" runat="server">
        <button id="Button1" runat="server" type="button" class="close" data-dismiss="alert">&times;</button>
        You shouldn't see this message!
    </div>
    <asp:Panel runat="server" ID="panMarquee" Visible="true">
        <div id="Div1" runat="server" class="progress progress-success progress-striped">
            <div id="ProgressBar" runat="server" class="bar" style="width: 100%"></div>
        </div>
    </asp:Panel>
</asp:Panel>

When the btnUpload button is clicked, the server code is supposed to determine if the FileUpload control has a file. If it does, it will change the visibility of the Panel control to true. It works fine outside of the UpdatePanel.

Here's the server code:

protected void btnUpload_Click(object sender, EventArgs e)
    {
        this.SetMessage(Message.Success);
        try
        {
            if (this.test.HasFile)
            {
                string filename = Path.GetFileName(GetUB04Doc.FileName);
                //test.SaveAs(Server.MapPath("~/") + filename);
                this.SetMessage(Message.Success);
            }
        }
        catch (Exception ex)
        {
            //TODO: Do something with th exception
            this.SetMessage(Message.Fail);
        }
        finally
        {
            //this.GetUB04Doc.Dispose();
        }
    }
private enum Message { Success, Fail }
    private void SetMessage(Message msg)
    {
        if (msg == Message.Success)
        {
            this.divAlert.InnerText = "Well done! The document appears to have uploaded successfully. Please wait...";
            this.divAlert.Attributes.Add("class", "alert alert-success");
        }
        else
        {
            this.divAlert.InnerText = "Oh snap! Something broke. Please contact IT right away.";
            this.divAlert.Attributes.Add("class", "alert alert-error");
        }

        this.panAlert.Visible = true;
    }

I tried putting the Panel in the ContentTemplate section as well, but the results were the same.

Any ideas on what I'm doing wrong here?


Solution

  • You should surround the area which you are modifying from an async postback in another UpdatePanel with UpdateMode is set to Conditional. Then update the other manually from codebehind:

    <asp:UpdatePanel ID="panAlertUpdatePanel" UpdateMode="Conditional" runat="server">
        <ContentTemplate>
        <asp:Panel runat="server" ID="panAlert" Visible="false">
            <!-- ....
    

    codebehind:

    // ...
    this.panAlert.Visible = true;
    panAlertUpdatePanel.Update()
    

    Side-note: As @Belogix has already commented, you should use an AsyncFileUpload control in an UpdatePanel since a regular FileUpload control it's not supported with an asynchronous postback.

    MSDN:

    Controls that Are Not Compatible with UpdatePanel Controls:

    • ...
    • FileUpload and HtmlInputFile controls when they are used to upload files as part of an asynchronous postback.
    • ...

    To use a FileUpload or HtmlInputFile control inside an UpdatePanel control, set the postback control that submits the file to be a PostBackTrigger control for the panel. The FileUpload and HtmlInputFile control can be used only in postback scenarios.