在更新面板内自动将文件上载到服务器第一次不起作用

Oza*_*ray 18 asp.net updatepanel webforms file-upload

要求

我正在尝试上传文件,只要用户选择它.我必须满足以下要求:

  1. 该按钮看起来像应用程序中的其他按钮.
  2. 用户选择文件后立即上传文件.
  3. 我需要它在UpdatePanel中,因为我必须对页面进行条件更新.我CAN做的文件中选择(又名完全回发onchange)事件.

目前的代码

以下是我的视图文件的外观:

<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>
Run Code Online (Sandbox Code Playgroud)

相关的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>
Run Code Online (Sandbox Code Playgroud)

代码背后:

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

说明/流量

  1. 用户点击btnFileImportSkin按钮.
  2. onImport调用该函数,以编程方式单击该fileimport按钮.
  3. 用户选择一个文件,然后按"打开".
  4. onFileSelected 叫做.
  5. onUpload 被称为成功.
  6. btnUpload_Click 每次都成功调用.

但是问题是,

用户第一次选择文件时,fileImport.PostedFile为null.一切都很好,第二次,从那里开始.

有关

这个问题与我的问题密切相关,但OP可能需要像Gmail一样的Async上传解决方案.我已经尝试过如下问题的答案:

  1. OnClientClick事件中的__doPostBack() btnUpload
  2. this.form.submit()我的FileUpload控件的onchange事件.
  3. FileUpload在Page_PreRender中设置控件的onchange属性

补充说明

  1. 当我没有更新面板时,这件事情完美无缺.我直接在onchange FileUpload控件事件中执行this.form.submit().
  2. 目标框架是.NET 4.0

注意:在FileUpload上面的控件中添加了Visible ="false" .这是问题,但在提出问题时我忽略了它.

Oza*_*ray 0

根据BeeTee 的回答、另一篇SO 帖子另一个论坛上的这个帖子的提示,我发现FileUpload控件在预渲染期间必须可见。对于该控件所在的任何父UpdatePanelVisible=false来说,这可能都是正确的。因此,基本上我从下面的控件定义中删除了:

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

就我而言,我可以通过将css opacity属性设置为 0 来隐藏它。但是,还有其他两种方法可以解决它:

  1. 设置CSS属性display:none
  2. 在预呈现期间将 asp 控件的 Visible 属性暂时设置为 true。上面从另一个论坛链接的线程中对此进行了详细说明。

请注意,Visible 对于此 FileUpload 控件的父级也应为 true,如其他 SO 线程中所述。