Uploading a file to server automatically inside an update panel does not work the first time

微笑、不失礼 提交于 2019-12-23 06:50:48

问题


Requirements

I am trying to upload a file, as soon as a user selects it. I have to fulfill the following requirements:

  1. The button looks like other buttons in the application.
  2. The file is uploaded as soon as the user selects it.
  3. I need it to be in an UpdatePanel as I have to make conditional updates to the page. I CAN do a full postback on the file selected (a.k.a onchange) event.

Current code

Following is how my view file looks:

<asp:UpdatePanel ID="upData" UpdateMode="Conditional" runat="server">
    <ContentTemplate>

    <div style="width: auto; float: right;">

    <asp:Button ID="btnFileImportSkin" CssClass="ButtonSkin AddButton" Text="Import" Style="position: absolute; z-index: 2;" runat="server" OnClientClick="Javascript:onImport(); return false;" />
    <asp:FileUpload ID="fileImport" Visible="false" Style="position:relative; opacity:0;" runat="server" onchange="Javascript:onFileSelected();"  /> 
           <%-- onchange="Javascript:this.form.submit();" /> --%>
           <%-- <asp:Button ID="btnUpload" runat="server" OnClientClick="Javascript:alert('Uploading...'); __doPostBack('<%= btnUpload.ID %>', ''); return false;" /> --%>
    <asp:Button ID="btnUpload" OnClick="btnUpload_Click" runat="server" />
    </div>

    </ContentTemplate>
    <Triggers>
        <asp:PostBackTrigger ControlID="btnUpload" />
    </Triggers>
</asp:UpdatePanel>

Relevant Javascript:

<script type="text/javascript">
    function onImport() {
        var fileImportClientId = '<%= fileImport.ClientID %>';
        document.getElementById(fileImportClientId).click();
    }

    function onFileSelected() {
        alert("File Selected");
        // I have tried calling the function directly and with a timeout
        setTimeout(onUpload, 20);
    }

    function onUpload() {
        var btnUploadClientId = '<%= btnUpload.ClientID %>';
        document.getElementById(btnUploadClientId).click();
    }
</script>

Code behind:

protected void btnUpload_Click(object sender, EventArgs e)
{
    // PostedFile is null first time code gets here on user selecting a file
    if (fileImport.PostedFile != null)
    {
        if (fileImport.PostedFile.FileName.Length > 0)
        {
            ImportFromFile();
        }
    }
}

Explanation/Flow

  1. User clicks on btnFileImportSkin button.
  2. The function onImport is called, which programmatically clicks on the fileimport button.
  3. User selects a file, and presses Open.
  4. onFileSelected is called.
  5. onUpload is called successfully.
  6. btnUpload_Click is called successfully every time.

However the Problem is that

fileImport.PostedFile is null the first time user selects a file. Everything works fine the second time and from there on.

Related

This question is closely related to my problem, but the OP probably wanted an Async upload solution as in Gmail. I have already tried doing the following as in the answers to this question:

  1. __doPostBack() in OnClientClick event of btnUpload
  2. this.form.submit() onchange event of my FileUpload control.
  3. Setting the onchange attribute of FileUpload control in Page_PreRender

Additional Notes

  1. This thing worked perfectly when I did not have update panels. I was doing this.form.submit() directly in onchange event of FileUpload control.
  2. Target framework is .NET 4.0

NOTE: Added a Visible="false" in FileUpload control above. It was the problem but I had ignored it while asking question.


回答1:


This code works for me, when targeting both the .Net 4.5 and 4.0 framework versions. I copy / pasted your code into a new Web Forms application, and in both cases fileImport.PostedFile was not null, but contained the Stream of the image I selected.

Is there an issue in any of the other markup on your page? Or perhaps your page lifecycle? Is the html / javascript you posted on a User Control or a Web Form Page?




回答2:


With a hint from BeeTee's answer, another SO post and this thread on another forum, I found out that the FileUpload control must be visible during prerendering. This is probably true for any parent UpdatePanels this control lies in. So, basically I removed Visible=false from my control definition below:

<asp:FileUpload ID="fileImport" Visible="false" Style="position:relative; opacity:0;" runat="server" onchange="Javascript:onFileSelected();"  />

In my case I could hide it by setting the css opacity property to 0. However, there are two other ways around it:

  1. Set the css property display:none
  2. Make the asp control's Visible property temporarily to true during prerendering. This is detailed in the thread linked above from another forum.

Please note that the Visible should also be true for parents of this FileUpload control as mentioned in the other SO thread.



来源:https://stackoverflow.com/questions/34227505/uploading-a-file-to-server-automatically-inside-an-update-panel-does-not-work-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!