在更新面板内自动上传文件第一次无法正常工作

18

要求

我正在尝试在用户选择文件后立即上传文件。我必须满足以下要求:

  1. 按钮的外观应与应用程序中的其他按钮相同。
  2. 用户选择文件后立即上传文件。
  3. 我需要它在UpdatePanel中,因为我必须对页面进行条件更新。我可以在文件选择(即onchange事件)上执行完整的postback。

当前代码

以下是我的视图文件的样子:

<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>

相关的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>

后台代码:

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.

2个回答

3
这段代码可用于 .Net 4.5 和 4.0 框架版本。我将您的代码复制/粘贴到一个新的 Web Forms 应用程序中,在两种情况下,fileImport.PostedFile 都不为空,但包含所选图像的流。您的页面上是否存在其他标记问题?或者是页面生命周期的问题?您发布的 html / javascript 是用户控件还是 Web 表单页面?

HTML和JavaScript都在用户控件中。 - Ozair Kafray
你确定它第一次就能工作吗?当我第二次点击“btnFileImportSkin”时,它也对我有效。 - Ozair Kafray
是的,我确定,百分之百。 :) 我只需单击一次按钮,代码就会第一次命中断点,每次都是如此。 - BeeTee2
你是否认为将其放在用户控件中与我的问题有关? - Ozair Kafray
1
是的,我认为你的问题很可能出现在asp.net页面生命周期的某个地方。它在用户控件中并不一定是一个问题,只是Web表单页面生命周期中有更多的移动部件。然而,如果没有看到主页面、Web表单和用户控件,这很难诊断。包括.aspx和代码后台。我刚刚将你发布的代码从Web表单移动到了用户控件中,并在新的Web表单应用程序中运行成功,第一次点击仍然可以发布文件。 - BeeTee2
请注意我的编辑(注)。我已经解决了这个问题,但如果您能为此编辑您的答案,我也会接受它:),否则我会自己回答。赏金仍将归您所有。 - Ozair Kafray

0

BeeTee的答案、另一篇SO帖子以及另一个论坛上的讨论串的提示下,我发现在预呈现期间FileUpload控件必须可见。这对于该控件所在的任何父级UpdatePanels可能都是正确的。因此,基本上我从我的控件定义中删除了Visible=false

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

在我的情况下,我可以通过将css opacity属性设置为0来隐藏它。但是,还有两种方法可以解决:

  1. 设置css属性display:none
  2. 在渲染前将asp控件的Visible属性暂时设置为true。这在上面链接到的另一个论坛中有详细说明。

请注意,在其他SO线程中提到的FileUpload控件的父级也应该为Visible为true。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接