第一次在更新面板内自动将文件上传到服务器不起作用
Uploading a file to server automatically inside an update panel does not work the first time
要求
我正在尝试在用户选择文件后立即上传文件。我必须满足以下要求:
- 该按钮看起来像应用程序中的其他按钮。
- 用户选择文件后立即上传。
- 我需要它位于 UpdatePanel 中,因为我必须对页面进行有条件的更新。我 CAN 对所选文件 (a.k.a
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>
相关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
- 用户点击了
btnFileImportSkin
按钮。
- 函数
onImport
被调用,它以编程方式点击 fileimport
按钮。
- 用户选择一个文件,然后按“打开”。
onFileSelected
被调用。
onUpload
调用成功
btnUpload_Click
每次调用成功
然而问题是
fileImport.PostedFile 在用户第一次选择文件时为空。第二次之后一切正常。
相关
This question 与我的问题密切相关,但 OP 可能想要像 Gmail 中那样的异步上传解决方案。我已经尝试按照此问题的答案执行以下操作:
- __doPostBack() 在
btnUpload
的 OnClientClick 事件中
- this.form.submit() 我的
FileUpload
控件的 onchange 事件。
- 在Page_PreRender
中设置FileUpload
控件的onchange属性
补充说明
- 当我没有更新面板时,这个东西工作得很好。我直接在
FileUpload
控件的 onchange 事件中执行 this.form.submit() 。
- 目标框架是 .NET 4.0
注意:在上面的 FileUpload
控件中添加了一个 Visible="false"。就是这个问题,但我在提问时忽略了它。
此代码适用于同时针对 .Net 4.5 和 4.0 框架版本的我。我将您的代码复制/粘贴到一个新的 Web 窗体应用程序中,在这两种情况下 fileImport.PostedFile 都不为空,但包含我选择的图像流。
您页面上的任何其他标记是否存在问题?或者您的页面生命周期?您在用户控件或 Web 表单页面上发布的 html / javascript?
根据 , another SO post and this thread on another forum 的提示,我发现 FileUpload 控件 必须在预呈现期间可见 。对于此控件所在的任何父 UpdatePanels 来说,这可能是正确的。因此,基本上我从下面的控件定义中删除了 Visible=false
:
<asp:FileUpload ID="fileImport" Visible="false" Style="position:relative; opacity:0;" runat="server" onchange="Javascript:onFileSelected();" />
在我的例子中,我可以通过将 css opacity
属性 设置为 0 来隐藏它。但是,还有其他两种方法周围:
- 设置css属性
display:none
- 在预呈现期间使 asp 控件的 Visible 属性 暂时变为 true。这在上面从另一个论坛链接的线程中有详细说明。
请注意,如其他 SO 线程中所述,对于此 FileUpload 控件的父级,Visible 也应为真。
要求
我正在尝试在用户选择文件后立即上传文件。我必须满足以下要求:
- 该按钮看起来像应用程序中的其他按钮。
- 用户选择文件后立即上传。
- 我需要它位于 UpdatePanel 中,因为我必须对页面进行有条件的更新。我 CAN 对所选文件 (a.k.a
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>
相关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
- 用户点击了
btnFileImportSkin
按钮。 - 函数
onImport
被调用,它以编程方式点击fileimport
按钮。 - 用户选择一个文件,然后按“打开”。
onFileSelected
被调用。onUpload
调用成功btnUpload_Click
每次调用成功
然而问题是
fileImport.PostedFile 在用户第一次选择文件时为空。第二次之后一切正常。
相关
This question 与我的问题密切相关,但 OP 可能想要像 Gmail 中那样的异步上传解决方案。我已经尝试按照此问题的答案执行以下操作:
- __doPostBack() 在
btnUpload
的 OnClientClick 事件中
- this.form.submit() 我的
FileUpload
控件的 onchange 事件。 - 在Page_PreRender 中设置
FileUpload
控件的onchange属性
补充说明
- 当我没有更新面板时,这个东西工作得很好。我直接在
FileUpload
控件的 onchange 事件中执行 this.form.submit() 。 - 目标框架是 .NET 4.0
注意:在上面的 FileUpload
控件中添加了一个 Visible="false"。就是这个问题,但我在提问时忽略了它。
此代码适用于同时针对 .Net 4.5 和 4.0 框架版本的我。我将您的代码复制/粘贴到一个新的 Web 窗体应用程序中,在这两种情况下 fileImport.PostedFile 都不为空,但包含我选择的图像流。
您页面上的任何其他标记是否存在问题?或者您的页面生命周期?您在用户控件或 Web 表单页面上发布的 html / javascript?
根据 Visible=false
:
<asp:FileUpload ID="fileImport" Visible="false" Style="position:relative; opacity:0;" runat="server" onchange="Javascript:onFileSelected();" />
在我的例子中,我可以通过将 css opacity
属性 设置为 0 来隐藏它。但是,还有其他两种方法周围:
- 设置css属性
display:none
- 在预呈现期间使 asp 控件的 Visible 属性 暂时变为 true。这在上面从另一个论坛链接的线程中有详细说明。
请注意,如其他 SO 线程中所述,对于此 FileUpload 控件的父级,Visible 也应为真。