2009-02-20 15 views

risposta

121

Nel vostro aspx:

<form id="form1" runat="server" enctype="multipart/form-data"> 
<input type="file" id="myFile" name="myFile" /> 
<asp:Button runat="server" ID="btnUpload" OnClick="btnUploadClick" Text="Upload" /> 
</form> 

Nel codice dietro:

protected void btnUploadClick(object sender, EventArgs e) 
{ 
    HttpPostedFile file = Request.Files["myFile"]; 

    //check file was submitted 
    if (file != null && file.ContentLength > 0) 
    { 
     string fname = Path.GetFileName(file.FileName); 
     file.SaveAs(Server.MapPath(Path.Combine("~/App_Data/", fname))); 
    } 
} 
+3

@mathieu, peccato che la tua variante usi 'runat =" server "', non è indipendente dalla roba del server di ASP.NET – Secret

+0

e se ci sono più di 1 ingressi e vuoi eseguire funzioni separate con entrambi i set di File. –

+0

mentre lo utilizza per caricare più file, restituisce lo stesso nome file per tutti i file e quindi salva il primo file n numero di volte. Qualche idea su come superarlo? – sohaiby

2

HtmlInputFile control

Ho usato questo per tutto il tempo.

+1

che richiede l'aggiunta di 'runat = "server"' che si trasforma in sostanza in un controllo server, che non volevano usare. – ahwm

8

utilizzare il controllo HTML con un attributo runat server di

<input id="FileInput" runat="server" type="file" /> 

Poi in asp.net Codebehind

FileInput.PostedFile.SaveAs("DestinationPath"); 

Ci sono anche alcune 3'rd party opzioni che vi mostrerà il progresso se si intrested

+2

Anche in questo caso, si trasforma in un controllo server. ;) – ahwm

21

È necessario impostare l'attributo di form a multipart/form-data; quindi è possibile accedere al file caricato utilizzando la raccolta HttpRequest.Files.

+0

Il mio modulo server era su una pagina principale e non potevo aggiungere multipart/form-data (da allora sarebbe su ogni pagina). Una soluzione rapida e sporca consisteva nell'aggiungere un controllo FileUpload nascosto alla pagina. WebForms ha quindi aggiunto automaticamente i dati multipart/form. Dovevo farlo perché stavo usando un file input con Angular2 e non potevo usare un controllo server in un modello di componente. – Jason

4

La raccolta Request.Files contiene tutti i file caricati con il modulo, indipendentemente dal fatto che provengano da un controllo FileUpload o da uno scritto manualmente <input type="file">.

Quindi è sufficiente scrivere un semplice tag di input di file vecchio nel mezzo del Web Form, quindi leggere il file caricato dalla raccolta Request.Files.

36

Ecco una soluzione senza fare affidamento su alcun controllo sul lato server, proprio come OP ha descritto nella domanda.

client codice lato HTML:

<form action="upload.aspx" method="post" enctype="multipart/form-data"> 
    <input type="file" name="UploadedFile" /> 
</form> 

metodo Page_Load di Upload.aspx:

if(Request.Files["UploadedFile"] != null) 
{ 
    HttpPostedFile MyFile = Request.Files["UploadedFile"]; 
    //Setting location to upload files 
    string TargetLocation = Server.MapPath("~/Files/"); 
    try 
    { 
     if (MyFile.ContentLength > 0) 
     { 
      //Determining file name. You can format it as you wish. 
      string FileName = MyFile.FileName; 
      //Determining file size. 
      int FileSize = MyFile.ContentLength; 
      //Creating a byte array corresponding to file size. 
      byte[] FileByteArray = new byte[FileSize]; 
      //Posted file is being pushed into byte array. 
      MyFile.InputStream.Read(FileByteArray, 0, FileSize); 
      //Uploading properly formatted file to server. 
      MyFile.SaveAs(TargetLocation + FileName); 
     } 
    } 
    catch(Exception BlueScreen) 
    { 
     //Handle errors 
    } 
} 
+0

Ottimo, questo ha risolto anche il mio problema! – Etienne

+0

Fare attenzione alla chiamata HTTPWebRequest che invia il percorso completo del file in MyFile.FileName. La chiamata WebClient invia solo il nome del file. HTTPWebRequest causerà il fallimento di MyFile.SaveAs. Solo ore sprecate a inseguire un cliente che lavora e un cliente no. –

6

Sì, è possibile raggiungere questo obiettivo con il metodo di posta ajax. sul lato server è possibile utilizzare httphandler. Quindi non stiamo usando alcun controllo server secondo i vostri requisiti.

con ajax è possibile visualizzare anche l'avanzamento del caricamento.

si dovrà leggere il file come inputstream.

using (FileStream fs = File.Create("D:\\_Workarea\\" + fileName)) 
    { 
     Byte[] buffer = new Byte[32 * 1024]; 
     int read = context.Request.GetBufferlessInputStream().Read(buffer, 0, buffer.Length); 
     while (read > 0) 
     { 
      fs.Write(buffer, 0, read); 
      read = context.Request.GetBufferlessInputStream().Read(buffer, 0, buffer.Length); 
     } 
    } 

codice di esempio

function sendFile(file) {    
     debugger; 
     $.ajax({ 
      url: 'handler/FileUploader.ashx?FileName=' + file.name, //server script to process data 
      type: 'POST', 
      xhr: function() { 
       myXhr = $.ajaxSettings.xhr(); 
       if (myXhr.upload) { 
        myXhr.upload.addEventListener('progress', progressHandlingFunction, false); 
       } 
       return myXhr; 
      }, 
      success: function (result) {      
       //On success if you want to perform some tasks. 
      }, 
      data: file, 
      cache: false, 
      contentType: false, 
      processData: false 
     }); 
     function progressHandlingFunction(e) { 
      if (e.lengthComputable) { 
       var s = parseInt((e.loaded/e.total) * 100); 
       $("#progress" + currFile).text(s + "%"); 
       $("#progbarWidth" + currFile).width(s + "%"); 
       if (s == 100) { 
        triggerNextFileUpload(); 
       } 
      } 
     } 
    } 
+0

Forse dovresti aggiungere il suggerimento per aggiungere un '' 'fs.close()' '' tutto il resto potrebbe finire in file illeggibili poiché rimangono in qualche modo aperti in IIS. – mistapink

3

Come altri ha risposta, i Request.Files è un HttpFileCollection che contiene tutti i file che sono stati pubblicati, avete solo bisogno di chiedere tale oggetto per il file in questo modo:

Request.Files["myFile"] 

Ma cosa capita quando ci sono più di un mark-up di ingresso con lo stesso nome di attributo:

Select file 1 <input type="file" name="myFiles" /> 
Select file 2 <input type="file" name="myFiles" /> 

Sul lato server, il codice precedente Request.Files ["myFile"] restituisce solo un oggetto HttpPostedFile anziché i due file. Ho visto su .NET 4.5 un metodo di estensione chiamato GetMultiple ma per le versioni prevoious esso non esiste, se è per questo vi propongo il metodo di estensione come:

public static IEnumerable<HttpPostedFile> GetMultiple(this HttpFileCollection pCollection, string pName) 
{ 
     for (int i = 0; i < pCollection.Count; i++) 
     { 
      if (pCollection.GetKey(i).Equals(pName)) 
      { 
       yield return pCollection.Get(i); 
      } 
     } 
} 

Questo metodo di estensione restituirà tutti gli oggetti che hanno HttpPostedFile il nome "myFiles" in HttpFileCollection se esiste.

0
//create a folder in server (~/Uploads) 
//to upload 
File.Copy(@"D:\CORREO.txt", Server.MapPath("~/Uploads/CORREO.txt")); 

//to download 
      Response.ContentType = ContentType; 
      Response.AppendHeader("Content-Disposition", "attachment;filename=" + Path.GetFileName("~/Uploads/CORREO.txt")); 
      Response.WriteFile("~/Uploads/CORREO.txt"); 
      Response.End(); 
+0

Usa il tasto '{}' per formattare il tuo post. In questo momento sembra un testo spazzatura. – Raju

Problemi correlati