ASP.NET MVC 4: Realizando Upload e download de arquivos
Veja nesse artigo como funciona o desenvolvimento em camada através do desenvolvimento de uma aplicação que fará o download e o upload de imagens.
Artigos .NET ASP.NET MVC 4: Realizando Upload e download de arquivos
Neste artigo desenvolveremos uma aplicação em ASP.NET MVC 4 que será responsável por realizar o upload de imagens e também disponibilizá-las em seguida para download para o usuário, com o intuito principal de auxiliar desenvolvedores que estão em processo de migração para o MVC Framework. Neste artigo usaremos o Visual Studio 2012 e o plugin jQuery MultiFile.
Iniciaremos entendendo a filosofia de como o MVC trabalha com arquivos e diretórios: o ActionResult é a classe abstrata retornada por cada método das Actions. Várias classes herdam da ActionResult, inclusive a FileResult, que é responsável pelo envio de conteúdo do arquivo binário para o response. Vamos ver a seguir um pouco sobre essas classes:
ViewResult : Responsável por exibir uma View.
ContentResult : Retorna apenas texto.
FileResult : A saída é o conteúdo de um arquivo.
JavaScriptResult : A saída para o conteúdo de um arquivo JavaScript.
JSonResult : Retorna as anotações do Json.
Vamos montar nosso ambiente criando uma aplicação ASP.NET MVC 4 Web Aplicattion usando o template InternetApllication e Razor como viewengine com o nome de MvcDownUpload no visual studio 2012, como mostrado nas Figuras 1 e 2.
Figura 1. Criação do projeto no visual studio 2012
Figura 2. Template InternetApplication com Razor
De início, nos preocuparemos em montar a estrutura da nossa aplicação. Para isso, criaremos uma classe Model que representará o arquivo com que a aplicação irá trabalhar. Nela irá conter as seguintes propriedades: Nome, Tamanho, Tipo e Caminho, como mostrado na Listagem 1.
public class UploadFileResult
public int IDArquivo { get; set; }
public int Tamanho{ get; set; }
public string Tipo{ get; set; }
public string Caminho { get; set; }
Listagem 1. Código fonte do model
No próximo passo criaremos nossa classe Controller FileUpload que será responsável por realizar todo o trabalho de importação do arquivo, como mostrado na Listagem 2.
// GET: /FileUpload/
int arquivosSalvos = 0;
HttpPostedFileBase arquivo = Request.Files[i];
//Suas validações ......
//Salva o arquivo
if (arquivo.ContentLength > 0)
var uploadPath = Server.MapPath("~/Content/Uploads");
string caminhoArquivo = Path.Combine(@uploadPath,
Path.GetFileName(arquivo.FileName));
arquivo.SaveAs(caminhoArquivo);
arquivosSalvos++;
ViewData["Message"] = String.Format("{0} arquivo(s) salvo(s) com sucesso.",
arquivosSalvos);
Listagem 2. Código fonte do Controller FileUpload
Agora precisaremos adicionar o plugin jQuery MultiFile ao nosso projeto. Para isso, clicaremos com o botão direito na pasta scripts e em seguida add existing item. Em seguida, localize onde foram salvos seus arquivos do plugin e clique em Add para todos, como mostrado na Figura 3.
Figura 3. Adicionando as referencias ao jQuery MultiFile
Nota: Para realizarem o download do plugin basta clicarem no link: FYNEWORKS
Por último, criaremos nossa camada de interface, adicionando de início duas Views chamadas index e upload, como mostrado nas Figuras 4 e 5.
Figura 4. Estrutura da View Upload
Figura 5. Estrutura da View index
Como vocês puderam notar, a estrutura das views de início é bem simples, formada por tags básicas do HTML, mas para fazermos nosso componente de upload funcionar devemos implementar uma função JavaScript e adicionarmos as referências aos arquivos .Js do plugin na tag Head da view Upload, como na Listagem 3.
<link href="~/Content/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap/bootstrap-theme.min.css" rel="stylesheet" />
<script src="~/Scripts/jquery.MultiFile.js"></script>
$('#file').MultiFile({
accept: 'gif|jpg',
remove: 'Remover',
denied: 'Tipo do arquivo inválido $ext!',
duplicate: 'Esse arquivo já foi selecionado:\n$file!'
Listagem 3. Função JavaScript responsável pelo Upload
Executaremos nossa aplicação para verificarmos como está o funcionamento desse primeiro fluxo, conforme mostrado na Figura 6.
Figura 6. Selecionando arquivo na View Upload
Na view Upload escolheremos o arquivo local que desejamos mandar e clicaremos no botão enviar, a aplicação executará nossa Action FileUpload criada anteriormente e realizará a importação do arquivo como mostrado na Figura 7.
Figura 7. Importação realizada com sucesso
Para comprovarmos que o arquivo foi importado, basta irmos à pasta onde escolhemos que nossos arquivos seriam salvos, que no caso é Content/Uploads, e verificarmos a existência dos mesmos, como mostrado na Figura 8.
Figura 8. Arquivos importados na pasta do projeto
Na segunda parte trataremos de desenvolver a lógica que listará nossos arquivos e os disponibilizará para download, onde primeiramente criaremos no nosso model UploadResult um método responsável por "pegar" os arquivos disponíveis, como mostrado na Listagem 4.
public List<UploadFileResult> ListaArquivos()
DirectoryInfo dirInfo = new DirectoryInfo(Server.MapPath("~/Content/Uploads"));
Listagem 4. Método de Listagem dos arquivos
Em seguida, definiremos o nosso Controller responsável pelos downloads, como mostrado na Listagem 5.
UploadFileResult oModelArquivos = new  UploadFileResult();
var _arquivos = oModelArquivos.ListaArquivos();
var arquivos = oModelArquivos.ListaArquivos();
where arquivo.IDArquivo == _arquivoId
select arquivo.Caminho).First();
return File(nomeArquivo, contentType, "Report.pdf");
Listagem 5. Fonte do Controller de Download
Na Listagem 6 criaremos nossa view de interface com o usuário.
@model IList<MvcDownUpload.Models.UploadFileResult>
@Html.ActionLink("Importar Novo", "Upload")
@Html.DisplayFor(modelItem => item.IDArquivo)
@Html.ActionLink("Download", "Download", new { id = item.IDArquivo })
Listagem 6. Fonte da View Index do Controller de Downloads
Note que criamos essa view do tipo do nosso model UploadFileResult para que assim pudéssemos ter acesso a suas propriedades e, a partir dele, executaremos nossa Action Download que disponibilizará o arquivo para o cliente. Para testarmos vamos executar nossa aplicação mais uma vez, como mostrado na Figura 9.
Figura 9. View download listando os arquivos
Ao clicarmos em um arquivo será disponibilizada a janela de download, como mostrado na Figura 10.
Figura 10. Janela de Download do arquivo escolhido
Para finalizarmos vamos dar uma melhorada na nossa aplicação tirando a amarração feita no código fonte para que o download seja gerado apenas em formato .pdf. Para isso, realizaremos uma pequena alteração na nossa Action de download, como mostra a Listagem 7.
var arquivos = oModelArquivos.ListaArquivos(Server.MapPath("~/Content/Uploads"));
string extensao = Path.GetExtension(nomeArquivo);
string nomeArquivoV = Path.GetFileNameWithoutExtension(nomeArquivo);
if (extensao.Equals(".pdf"))
if (extensao.Equals(".JPG") || extensao.Equals(".GIF") || extensao.Equals(".PNG"))
contentType = "application/image";
return File(nomeArquivo, contentType, nomeArquivoV+extensao);
Listagem 7. Fonte do Controller de Downloads Alterado
Fazendo isso assim que recuperarmos nosso arquivo escolhido para download pelo id, poderemos recuperar sua extensão e atribuirmos o contentType adequado.