Come posso ottenere un modulo Web ASP.net (v3.5) per inviare un file utilizzando un vecchio semplice <input type="file" />
?
Non mi interessa utilizzare il controllo server FileUpload di ASP.net.
Come posso ottenere un modulo Web ASP.net (v3.5) per inviare un file utilizzando un vecchio semplice <input type="file" />
?
Non mi interessa utilizzare il controllo server FileUpload di ASP.net.
Risposte:
Nel tuo 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)));
}
}
var fileUploaded = document.getElementById("myFile").files[0];
e puoi persino ottenere i byte usando readAsArrayBuffer
: stackoverflow.com/questions/37134433/… - ma cosa farai con tutti quei byte lato client? L'OP vuole evitare del tutto la comunicazione lato server e controllo ASP .NET. -1 a te.
Ecco una soluzione senza fare affidamento su alcun controllo lato server, proprio come OP ha descritto nella domanda.
Codice HTML lato client:
<form action="upload.aspx" method="post" enctype="multipart/form-data">
<input type="file" name="UploadedFile" />
</form>
Page_Load metodo 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
}
}
Request.Files[0]
posto di Request.Files["UploadedFile"]
e mentre l'OP utilizzava ASP .NET e non MVC, se qualcuno vuole usarlo per MVC, è sufficiente HttpPostedFileBase
invece di HttpPostedFile
.
Dovrai impostare l' enctype
attributo del form
to multipart/form-data
; quindi puoi accedere al file caricato utilizzando la HttpRequest.Files
raccolta.
utilizzare il controllo HTML con un attributo del server runat
<input id="FileInput" runat="server" type="file" />
Quindi in asp.net Codebehind
FileInput.PostedFile.SaveAs("DestinationPath");
Ci sono anche alcune opzioni di terze parti che mostreranno i progressi se sei interessato
<asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>
) Questo è diverso dal dire di non mettere un runat=server
in un input
campo.
HtmlInputFile
controllo.
Sì, puoi ottenerlo con il metodo ajax post. lato server puoi usare httphandler. Quindi non stiamo utilizzando alcun controllo del server secondo le tue esigenze.
con ajax puoi anche mostrare l'avanzamento del caricamento.
dovrai 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();
}
}
}
}
fs.close()
tutto il resto potrebbe finire in file illeggibili poiché rimangono in qualche modo aperti all'interno di IIS.
La raccolta Request.Files contiene tutti i file caricati con il modulo, indipendentemente dal fatto che provengano da un controllo FileUpload o da un <input type="file">
.
Quindi puoi semplicemente scrivere un semplice vecchio tag di input del file nel mezzo del tuo WebForm, quindi leggere il file caricato dalla raccolta Request.Files.
Come altri hanno risposto, Request.Files è un HttpFileCollection che contiene tutti i file che sono stati pubblicati, devi solo chiedere a quell'oggetto il file in questo modo:
Request.Files["myFile"]
Ma cosa succede quando ci sono più markup di input 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 un solo oggetto HttpPostedFile invece dei due file. Ho visto su .net 4.5 un metodo di estensione chiamato GetMultiple ma per le versioni precedenti non esiste, del resto 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 HttpPostedFile che hanno il nome "myFiles" in HttpFileCollection, se presente.
L'ho usato tutto il tempo.
runat="server"
che essenzialmente lo trasforma in un controllo server, che non volevano usare.
Ecco un articolo di Code Project con un progetto scaricabile che pretende di risolvere questo problema. Disclaimer: non ho testato questo codice. http://www.codeproject.com/KB/aspnet/fileupload.aspx
//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();
runat="server"
, non è indipendente dalla roba del server di ASP.NET