2015-12-11 29 views
18

RequisitiCaricamento di un file a un server automaticamente all'interno di un pannello di aggiornamento non funziona la prima volta

Sto cercando di caricare un file, non appena un utente lo seleziona. Devo soddisfare i seguenti requisiti:

  1. Il pulsante ha l'aspetto di altri pulsanti dell'applicazione.
  2. Il file viene caricato non appena l'utente lo seleziona.
  3. Ho bisogno che sia in un UpdatePanel poiché devo apportare aggiornamenti condizionali alla pagina. I CAN fare un postback completo sul file selezionato (a.k.a onchange) evento.

codice attuale

seguito è come il mio file vista sembra:

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

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

codice dietro:

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(); 
     } 
    } 
} 
01 scatta

Spiegazione/flusso

  1. utente su btnFileImportSkin tasto.
  2. Si chiama la funzione onImport, che fa clic programmaticamente sul pulsante fileimport.
  3. L'utente seleziona un file e preme Apri.
  4. onFileSelected viene chiamato.
  5. onUpload viene chiamato correttamente.
  6. btnUpload_Click viene chiamato con successo ogni volta.

Tuttavia il problema è che

fileImport.PostedFile è nullo l'utente prima volta seleziona un file. Tutto funziona bene la seconda volta e da lì in poi.

correlati

This question è strettamente legato al mio problema, ma il PO probabilmente voleva una soluzione di upload Async come in Gmail. Ho già provato a fare il seguente come nelle risposte a questa domanda:

  1. __doPostBack() in caso di OnClientClick btnUpload
  2. this.form.submit() onchange evento dal mio controllo FileUpload.
  3. impostazione dell'attributo onchange di FileUpload controllo Page_PreRender

note aggiuntive

  1. Questa cosa ha funzionato perfettamente quando non ho avuto pannelli di aggiornamento. Stavo facendo this.form.submit() direttamente nell'evento onchange del controllo FileUpload.
  2. framework di destinazione è .NET 4,0

NOTA: Aggiunto un Visible = "false" in FileUpload controllo di cui sopra. Era il problema ma l'avevo ignorato mentre facevo domande.

risposta

0

Con una punta da BeeTee's answer, un'altra SO post e this thread on another forum, ho scoperto che la FileUpload controllo deve essere visibile durante prerendering. Questo è probabilmente vero per qualsiasi genitore UpdatePanels si trova questo controllo in Quindi, in pratica ho rimosso Visible=false dalla mia definizione del controllo di seguito:.

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

Nel mio caso ho potuto nasconderlo impostando il cssopacity proprietà 0. Tuttavia, ci sono altri due modi intorno ad esso:

  1. Impostare il css proprietà display:none
  2. Marchio la proprietà Visible del controllo asp temporaneamente su true durante il prerendering. Questo è dettagliato nel thread collegato sopra da un altro forum.

Si prega di notare che Visible dovrebbe essere vero anche per i genitori di questo controllo FileUpload come menzionato nell'altro thread SO.

3

Questo codice funziona per me, quando si targetizza entrambe le versioni .Net 4.5 e 4.0. Ho copiato/incollato il codice in una nuova applicazione Web Forms e in entrambi i casi fileImport.PostedFile non era nullo, ma conteneva il flusso dell'immagine che ho selezionato.

C'è un problema in uno degli altri markup sulla tua pagina? O forse il tuo ciclo di vita della pagina? Html/javascript è stato pubblicato su un controllo utente o una pagina Web Form?

+0

Sia html che javascript si trovano in un controllo utente. –

+0

Sei sicuro che funzioni la prima volta? Funziona anche per me quando clicco su "btnFileImportSkin' la seconda volta. –

+0

Sì, lo sono, 110%. :) Faccio clic sul pulsante solo una volta e il codice raggiunge il punto di interruzione la prima volta, ogni volta. – BeeTee2