Apesar do título grande e, para uns, confuso, nesse tópico irei ajudar muitos a resolver um problema: múltiplos uploads de vez sem precisar selecionar cada arquivo.
A idéia primordial é fazer com que o usuário possa clicar em um botão, selecionar vários arquivos de vez (que nem o GMail) e fazer o envio para uma pasta desejada. Para isso iremos utilizar um Handler em C# para fazer o upload. Mas nesse mesmo Handler irei escrever na sessão para que possa utilizar em outra página. Lembrando que as variáveis de sessão, para usar dentro de um Handler precisa-se de um artifício. Sem mais delongas, vamos à solução.
Crie ou abra um Web Site Project e nele adicione um Generic Handler. Coloque com o nome Upload.ashx para ficar mais fácil de encontrá-lo. Insira o seguinte cógido:
using System;
using System.Data;
using System.IO;
using System.Web;
using System.Web.SessionState;
public class Upload : IHttpHandler, IRequiresSessionState{
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.Expires = -1;
try
{
// Obtêm o arquivo a ser postado
HttpPostedFile postedFile = context.Request.Files["filedata"];
// Caminho
string path = context.Server.MapPath("~/Upload/");
string filename = postedFile.FileName;
// Cria diretório de não existir
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
// Verifica se o arquivo já existe com mesmo nome
string nome = filename.Substring(0, filename.LastIndexOf("."));
string extensao = filename.Substring(filename.LastIndexOf(".") + 1);
int i = 1;
// Verifica se existe, senão renomeia
while (File.Exists(path + @"\" + filename))
{
filename = nome + "(" + i + ")." + extensao;
i++;
}
// Adiciona na sessão
DataTable galeria = (DataTable)context.Session["galeria"];
DataRow item = galeria.NewRow();
item["imagem"] = filename;
galeria.Rows.Add(item);
context.Session["galeria"] = galeria;
// Salva arquivo
postedFile.SaveAs(path + @"\" + filename);
// Retorna o arquivo salvo
context.Response.Write(path + "/" + filename);
context.Response.StatusCode = 200;
}
catch (Exception ex)
{
context.Response.Write("Erro: " + ex.Message);
}
}
public bool IsReusable {
get {
return true;
}
}
}
Pronto! Já temos nosso Handler que faz o upload de um arquivo e o adiciona em um DataTable. Esse DataTable já estava previamente adicionado na sessão. Você pode utilizar quaisquer outra estrutura para armazenar. A dica da escrita na sessão no Handler está na herança da interface IRequiresSessionState onde permitirá fazer isso.
Crie uma página ASPX e referencie os JavaScripts do JQuery abaixo (os arquivos, caso não possuam, irei disponibilizar em um link abaixo) e um CSS pra dar um estilo legal:
<link rel="stylesheet" type="text/css" href="css/stilo.css" />
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/jquery.uploadify.js"></script>
Agora adicione um controle FileUpload e um link (ou um controle HyperLink). Iremos também fazer a chamada do JQuery para ser aplicado sobre o FileUpload ficando dessa forma:
<asp:FileUpload ID="Fotos" runat="server" />
<input type="button" onclick="javascript:$('#<%=Fotos.ClientID%>').fileUploadStart();" value="Enviar" />
<script type="text/javascript">
$(window).load(
function() {
$("#<%=Fotos.ClientID %>").fileUpload({
'uploader': 'js/uploader.swf',
'cancelImg': 'imagens/cancelar.png',
'buttonText': 'Selecionar',
'script': 'Upload.ashx',
'folder': 'Upload',
'fileDesc': 'Selecione arquivos do tipo imagem',
'fileExt': '*.jpg;*.jpeg;*.gif;*.png',
'multi': true,
'auto': false
});
}
);
</script>
Agora rode a aplicação. Verá apenas um botão com o nome Selecionar. Ao clicar irá abrir um pop-up pedindo para selecionar os arquivos. Selecione um ou mais e clique em OK. Verá que será montado uma lista com os arquivos que irão ser enviados. Você poderá remover itens clicando no X sobre cada um deles. Ao clicar no link Enviar, será feito uma chamada para cada item sobre o Handler fazendo o envio para a pasta Upload e adicionando no DataTable armazenado na sessão.
Não vou entrar muito em datelhes, porque está bem fácil e compreensível o código. Se desejar, ao invés de clicar em Enviar para fazer o envio, você pode deixar automático (como se fosse uma trigger) mudando o parâmetro 'auto' para true da chamada JQuery. Então, ao selecionar e clicar em OK automaticamente será feito o upload. Se também quiser que o link faça um PostBack na página, basta colocar depois da chamada de início do upload, insira o __doPostBack('',''); colocando parâmetro ou não dependendo do que for fazer com ele após.
Nesse link aqui encontram-se alguns arquivos necessários para que possam utilizar. Não vou colocar os fontes ASP.NET porque senão já seria demais, né? Mãos à obra...
Obs: a fonte e outras matérias sobre o mesmo tópico você acha aí pela net. Não me lembro qual site eu havia visto algo do tipo e fiz essa. Mas fica a dica aí!