Como posso obter um formulário da web ASP.net (v3.5) para postar um arquivo usando um simples e antigo <input type="file" />
?
Não estou interessado em usar o controle de servidor FileUpload do ASP.net.
Como posso obter um formulário da web ASP.net (v3.5) para postar um arquivo usando um simples e antigo <input type="file" />
?
Não estou interessado em usar o controle de servidor FileUpload do ASP.net.
Respostas:
Em seu 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>
No código por trás de:
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 você pode até mesmo obter os bytes usando readAsArrayBuffer
: stackoverflow.com/questions/37134433/… - mas o que você vai fazer com todos esses bytes do lado do cliente? O OP deseja evitar completamente a comunicação do lado do servidor de controle e não do ASP .NET. -1 para você.
Aqui está uma solução sem depender de nenhum controle do lado do servidor, assim como o OP descreveu na pergunta.
Código HTML do 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]
vez de Request.Files["UploadedFile"]
e enquanto o OP estava usando ASP .NET puro e não MVC, se alguém quiser usar isso para MVC, você só precisa em HttpPostedFileBase
vez de HttpPostedFile
.
Você terá que definir o enctype
atributo de form
para multipart/form-data
; então você pode acessar o arquivo carregado usando a HttpRequest.Files
coleção.
use o controle HTML com um atributo de servidor runat
<input id="FileInput" runat="server" type="file" />
Então, em asp.net Codebehind
FileInput.PostedFile.SaveAs("DestinationPath");
Existem também algumas opções de terceiros que mostrarão o progresso se você se interessar
<asp:FileUpload ID="fileUpload1" runat="server"></asp:FileUpload>
) Isso é diferente de dizer para não colocar um runat=server
em um input
campo.
HtmlInputFile
controle.
Sim, você pode conseguir isso pelo método de postagem Ajax. no lado do servidor, você pode usar httphandler. Portanto, não estamos usando nenhum controle de servidor de acordo com sua necessidade.
com ajax você também pode mostrar o progresso do upload.
você terá que ler o arquivo como um fluxo de entrada.
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 amostra
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 o resto pode acabar em arquivos ilegíveis, já que eles permanecem abertos de alguma forma no IIS.
A coleção Request.Files contém todos os arquivos carregados com o seu formulário, independentemente de serem provenientes de um controle FileUpload ou escrito manualmente <input type="file">
.
Portanto, você pode simplesmente escrever uma tag de entrada de arquivo simples e antiga no meio de seu formulário da Web e, em seguida, ler o arquivo carregado da coleção Request.Files.
Como outros já responderam, o Request.Files é um HttpFileCollection que contém todos os arquivos que foram postados, você só precisa pedir a esse objeto o arquivo assim:
Request.Files["myFile"]
Mas o que acontece quando há mais de uma marcação de entrada com o mesmo nome de atributo:
Select file 1 <input type="file" name="myFiles" />
Select file 2 <input type="file" name="myFiles" />
No lado do servidor, o código anterior Request.Files ["myFile"] retorna apenas um objeto HttpPostedFile em vez dos dois arquivos. Eu vi no .net 4.5 um método de extensão chamado GetMultiple, mas para as versões anteriores ele não existe, por isso proponho o método de extensão 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 extensão retornará todos os objetos HttpPostedFile que possuem o nome "myFiles" em HttpFileCollection, se houver.
Eu usei isso o tempo todo.
runat="server"
que essencialmente o transforma em um controle de servidor, que eles não queriam usar.
Aqui está um artigo do Projeto de código com um projeto para download que pretende resolver isso. Isenção de responsabilidade: não testei 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"
, não é independente das coisas do servidor ASP.NET