¿Cómo puedo obtener un formulario web ASP.net (v3.5) para publicar un archivo usando un viejo simple <input type="file" />
?
No estoy interesado en usar el control de servidor ASP.net FileUpload.
¿Cómo puedo obtener un formulario web ASP.net (v3.5) para publicar un archivo usando un viejo simple <input type="file" />
?
No estoy interesado en usar el control de servidor ASP.net FileUpload.
Respuestas:
En tu 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>
En código detrás:
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 incluso puede obtener los bytes usando readAsArrayBuffer
: stackoverflow.com/questions/37134433/… - pero ¿qué va a hacer con todos esos bytes del lado del cliente? El OP quiere evitar por completo el control ASP .NET, no la comunicación del lado del servidor. -1 para ti.
Aquí hay una solución sin depender de ningún control del lado del servidor, tal como OP ha descrito en la pregunta.
Código HTML del lado del cliente:
<form action="upload.aspx" method="post" enctype="multipart/form-data">
<input type="file" name="UploadedFile" />
</form>
Método Page_Load de 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]
lugar de Request.Files["UploadedFile"]
y mientras el OP estaba usando ASP .NET directo y no MVC, si alguien quiere usar esto para MVC, solo necesita en HttpPostedFileBase
lugar de HttpPostedFile
.
Tendrá que establecer el enctype
atributo de form
to multipart/form-data
; luego puede acceder al archivo cargado usando la HttpRequest.Files
colección.
usar el control HTML con un atributo de servidor runat
<input id="FileInput" runat="server" type="file" />
Luego, en asp.net Codebehind
FileInput.PostedFile.SaveAs("DestinationPath");
También hay algunas opciones de terceros que mostrarán el progreso si está interesado
<asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>
) Eso es diferente a decir que no se ponga un runat=server
en un input
campo.
HtmlInputFile
control.
Sí, puede lograr esto mediante el método de publicación ajax. en el lado del servidor puede usar httphandler. Por lo tanto, no estamos utilizando ningún control de servidor según sus requisitos.
con ajax también puede mostrar el progreso de la carga.
tendrá que leer el archivo como 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);
}
}
Código de muestra
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()
todo lo demás podría terminar en archivos ilegibles, ya que permanecen abiertos de alguna manera dentro de IIS.
La colección Request.Files contiene todos los archivos cargados con su formulario, independientemente de si provienen de un control FileUpload o de un archivo <input type="file">
.
Por lo tanto, puede escribir una etiqueta de entrada de archivo simple y antigua en el medio de su WebForm y luego leer el archivo cargado desde la colección Request.Files.
Como otros han respondido, Request.Files es una HttpFileCollection que contiene todos los archivos que se publicaron, solo necesita pedirle a ese objeto el archivo de esta manera:
Request.Files["myFile"]
Pero, ¿qué sucede cuando hay más de un marcado de entrada con el mismo nombre de atributo?
Select file 1 <input type="file" name="myFiles" />
Select file 2 <input type="file" name="myFiles" />
En el lado del servidor, el código anterior Request.Files ["myFile"] solo devuelve un objeto HttpPostedFile en lugar de los dos archivos. He visto en .net 4.5 un método de extensión llamado GetMultiple pero para versiones anteriores no existe, para el caso propongo el método de extensión como:
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);
}
}
}
Este método de extensión devolverá todos los objetos HttpPostedFile que tienen el nombre "myFiles" en HttpFileCollection si existe alguno.
He usado esto todo el tiempo.
runat="server"
que esencialmente lo convierte en un control de servidor, que no querían usar.
Aquí hay un artículo de Code Project con un proyecto descargable que pretende resolver esto. Descargo de responsabilidad: no he probado este código. 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"
, no es independiente del servidor de ASP.NET