问题
Requirements
I am trying to upload a file, as soon as a user selects it. I have to fulfill the following requirements:
- The button looks like other buttons in the application.
- The file is uploaded as soon as the user selects it.
- 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
- User clicks on
btnFileImportSkin
button. - The function
onImport
is called, which programmatically clicks on thefileimport
button. - User selects a file, and presses Open.
onFileSelected
is called.onUpload
is called successfully.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:
- __doPostBack() in OnClientClick event of
btnUpload
- this.form.submit() onchange event of my
FileUpload
control. - Setting the onchange attribute of
FileUpload
control in Page_PreRender
Additional Notes
- This thing worked perfectly when I did not have update panels. I was doing this.form.submit() directly in onchange event of
FileUpload
control. - 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:
- Set the css property
display:none
- 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