É muito fácil de fazer um uploader usando componentes do Bootstrap com barra de progresso
Eu resolvi pegar meu artigo e código antigos pra atualizar. Por exemplo: Enquanto antes eu tinha usado o Visual Studio 2010 pra desenvolver um projeto em MVC3 agora eu estou usando o Visual Studio 2012 pra criar um projeto em ASP.NET MVC4 usando bootstrap e uma versão mais recente de todos os plugins que eu usei antes.
Primeiro passo
Antes de mais nada a gente precisa criar um Model do mesmo jeito que Scott Hanselman criou em seu artigo. Assim temos o nome (Name), tamanho (Length) e tipo (Type) do arquivo que vamos enviar pro servidor:
public class UploadFilesResult { public string Name { get; set; } public int Length { get; set; } public string Type { get; set; } }
Segundo passo
Agora nós precisamos de uma Action Method que vai efetivamente pegar o arquivo, tratar e salvar no servidor. Vamos chamar esta Action Method usando o método http POST, pegar a lista de arquivos selecionados e salvar dentro de App_Data. Esta Action Method vai retornar uma string em formato json com o Name, Length and Type dos arquivos:
[HttpPost] public ContentResult UploadFiles() { var r = new List<ViewDataUploadFilesResult>(); foreach (string file in Request.Files) { HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase; if (hpf.ContentLength == 0) continue; string savedFileName = Path.Combine(Server.MapPath("~/App_Data"), Path.GetFileName(hpf.FileName)); hpf.SaveAs(savedFileName); // Save the file r.Add(new ViewDataUploadFilesResult() { Name = hpf.FileName, Length = hpf.ContentLength, Type = hpf.ContentType }); } // Returns json return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}", "application/json"); }
Terceiro passo
Agora precisamos usar um plugin do jQuery chamado jQuery File Upload. Ele já traz nativamente um monte de coisa bacana mas, para simplificar, vamos usar apenas 2 arquivos (além de outros que já estou usando): jquery.fileupload.css and jquery.fileupload.js.
Quarto passo
Com isso a gente precisa de alguma maneira de enviar os arquivos. Isso é o que eu criei - apenas para o upload - mas você pode adaptar para seu projeto:
<div class="container"> <span class="btn btn-success fileinput-button"> <i class="glyphicon glyphicon-plus">i> <span>Add files...span> <input id="fileupload" type="file" name="files[]" multiple> span> <br /> <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"> <span class="sr-only">0% completespan> div> div> <br /> <div class="file_name">div> <br /> <div class="file_type">div> <br /> <div class="file_size">div> div>
Observe 4 coisas:
- Eu não usei nenhum HtmlHelper para criar o form. O motivo disso é a facilidade de se criar um form sem HtmlHelper, sem contar que não precisamos usar os HtmlHelpers o tempo todo;
- Eu não estou usando form tag. O plugin toma conta de tudo o que precisamos;
- A barra de progresso graças ao bootstrap;
- As divs no final. Elas só estão lá pra receber e mostrar o que o json trouxe..
Último passo
Depois de organizarmos é hora de fazer o javascript pra fazer isso tudo funcionar. Eu estou usando o plugin jQuery File Upload chamando a Action method UploadFiles criado no HomeController. Some isso ao evento que coloquei no javascript mostrando o status do upload usando a barra de progresso do bootstrap:
<script type="text/javascript"> $(document).ready(function () { $('#fileupload').fileupload({ dataType: 'json', url: '/Home/UploadFiles', autoUpload: true, done: function (e, data) { $('.file_name').html(data.result.name); $('.file_type').html(data.result.type); $('.file_size').html(data.result.size); } }).on('fileuploadprogressall', function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); $('.progress .progress-bar').css('width', progress + '%'); }); }); script>
É isso. Agora você está pronto pra colocar esse recurso no seu site. E sem postback!
Você pode baixar o código aqui: jQueryFileUploadMVC4.zip (5.84 MB). Sim, quase 6MB, graças aos packages do NuGet.