ASP .NET Core MVC - Upload de arquivos

 Neste artigo veremos fazer o Upload de arquivos para o servidor em uma aplicação ASP .NET Core MVC.

      

Usando métodos Action na ASP .NET Core MVC podemos fazer o upload de um ou mais arquivos usando o model binding para arquivos pequenos ou usando o streaming para arquivos maiores.

Para fazer o upload de arquivos pequenos podemos usar um formulário HTML multipart/form-data ou criar uma requisição POST usando JavaScript.

Usando um formulário HTML para dar suporte ao upload de arquivos devemos especificar o seguinte:

Assim, definindo esses elementos chegamos ao seguinte código de exemplo:

A seguir no método Action Index do controlador UploadFiles definimos o código para fazer o upload dos arquivos selecionados.

Para tratar os arquivos individuais enviados ao servidor podemos usar o Model Binding através da interface IFormFile que possui a seguinte estrutura:

public interface IFormFile
{
    string ContentType { get; }
    string ContentDisposition { get; }
    IHeaderDictionary Headers { get; }
    long Length { get; }
    string Name { get; }
    string FileName { get; }
    Stream OpenReadStream();
    void CopyTo(Stream target);
    Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
}

Arquivos carregados usando a técnica IFormFile são armazenados em buffer na memória ou no disco no servidor Web antes de serem processados. Dentro do método Action, o conteúdo de IFormFile pode ser acessado como um stream ou fluxo.

Além do sistema de arquivos local, os arquivos podem ser transmitidos para o Armazenamento de Blobs do Azure ou para o Entity Framework.

Para armazenar dados de um arquivo binário em um banco de dados usando o Entity Framework, geralmente definimos uma propriedade do tipo byte[] na entidade.

Neste artigo eu vou mostrar como enviar arquivos pequenos de até 30 MB que é a limitação imposta para envio de arquivos via Request na ASP .NET Core.

Para simplificar, neste artigo vamos enviar arquivos que serão armazenadas em uma pasta Recebidos dentro da pasta Arquivos_Usuario dentro da pasta Arquivos dentro da pasta wwwroot do projeto.

Assim teremos que criar no projeto a estrutura de arquivos para receber os arquivos enviados como mostrada abaixo:

Nota: Em outro arquivo vou mostrar como criar a estrutura em tempo de execução.

Recursos usados:

Criando o projeto no VS 2017

Vamos iniciar criando uma aplicação ASP .NET Core MVC usando o template padrão.

Abra o VS 2017 Community e crie um novo projeto ASP .NET Core usando o template Web Application(Model-View-Controller).

  • Create New Project;
  • Visual C# -> Web -> ASP .NET Core Web Application;
  • Informe o nome Aspn_Upload
  • Clique em OK e a seguir selecione o template Web Application(Model-View-Controller), marque ASP .NET Core 2.1 e as demais opções conforme mostra a figura abaixo e clique em OK;

Ao clicar no botão OK teremos o projeto criado com a estrutura abaixo:

Vamos usar esses recursos para criar nossa aplicação e fazer o upload de arquivos.

Criando o controlador UploadController

Vamos criar um controlador chamado UploadController na pasta Controllers e definir dois métodos Action :

  • Index - Representa o nosso formulário HTML onde vamos selecionar os arquivos a enviar;
  • EnviarArquivo - Define o código que vai enviar os arquivos selecionados;

Clique com o botão direito do mouse sobre a pasta Controllers e a seguir selecione Add -> Controller;

Selecione o template - MVC Controller Empty, e clique me Add;

Informe o nome UploadController e clique em Add.

A seguir vamos incluir o código abaixo o no controlador:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Aspn_Upload.Controllers
{
    public class UploadController : Controller
    {
        //Define uma instância de IHostingEnvironment
        IHostingEnvironment _appEnvironment;
        //Injeta a instância no construtor para poder usar os recursos
        public UploadController(IHostingEnvironment env)
        {
            _appEnvironment = env;
        }
        //Retorna a View Index.cshtml que será o formulário para
        //selecionar os arquivos a serem enviados 
        public IActionResult Index()
        {
            return View();
        }
        //método para enviar os arquivos usando a interface IFormFile
        public async Task<IActionResult> EnviarArquivo(List<IFormFile> arquivos)
        {
            long tamanhoArquivos = arquivos.Sum(f => f.Length);
            // caminho completo do arquivo na localização temporária
            var caminhoArquivo = Path.GetTempFileName();

            // processa os arquivo enviados
            //percorre a lista de arquivos selecionados
            foreach (var arquivo in arquivos)
            {
                //verifica se existem arquivos 
                if (arquivo == null || arquivo.Length == 0)
                {
                    //retorna a viewdata com erro
                    ViewData["Erro"] = "Error: Arquivo(s) não selecionado(s)";
                    return View(ViewData);
                }
                // < define a pasta onde vamos salvar os arquivos >
                string pasta = "Arquivos_Usuario";
                // Define um nome para o arquivo enviado incluindo o sufixo obtido de milesegundos
                string nomeArquivo = "Usuario_arquivo_" + DateTime.Now.Millisecond.ToString();
                //verifica qual o tipo de arquivo : jpg, gif, png, pdf ou tmp
                if (arquivo.FileName.Contains(".jpg"))
                    nomeArquivo += ".jpg";
                else if (arquivo.FileName.Contains(".gif"))
                    nomeArquivo += ".gif";
                else if (arquivo.FileName.Contains(".png"))
                    nomeArquivo += ".png";
                else if (arquivo.FileName.Contains(".pdf"))
                    nomeArquivo += ".pdf";
                else
                    nomeArquivo += ".tmp";
                //< obtém o caminho físico da pasta wwwroot >
                string caminho_WebRoot = _appEnvironment.WebRootPath;
                // monta o caminho onde vamos salvar o arquivo : 
                // ~\wwwroot\Arquivos\Arquivos_Usuario\Recebidos
                string caminhoDestinoArquivo = caminho_WebRoot + "\\Arquivos\\" + pasta + "\\";
                // incluir a pasta Recebidos e o nome do arquivo enviado : 
                // ~\wwwroot\Arquivos\Arquivos_Usuario\Recebidos\
                string caminhoDestinoArquivoOriginal = caminhoDestinoArquivo + "\\Recebidos\\" + nomeArquivo;
                //copia o arquivo para o local de destino original
                using (var stream = new FileStream(caminhoDestinoArquivoOriginal, FileMode.Create))
                {
                    await arquivo.CopyToAsync(stream);
                }
            }
            //monta a ViewData que será exibida na view como resultado do envio 
            ViewData["Resultado"] = $"{arquivos.Count} arquivos foram enviados ao servidor, " +
             $"com tamanho total de : {tamanhoArquivos} bytes";
            //retorna a viewdata
            return View(ViewData);
        }
    }
}

Agora vamos entender o código:

1 - No construtor do Controller injetamos uma instância de IHostingEnvironment para poder ter acesso às informações do ambiente.

Vamos obter caminho físico da pasta wwwroot do projeto.

No método Action Index apenas vai exibir a view Index.cshtml que iremos criar para selecionar os arquivos:

O restante do código já esta devidamente comentado.

Vamos agora criar a View Index.cshtml. Clique com o botão direito do mouse dentro do método Action Index e selecione a opção Add View;

Aceite os valores padrão informados na janela Add MVC View e clique em Add;

A seguir inclua o código abaixo na view Index.cshtml na pasta /Views/Upload:

Observe que estamos postando as informações para o controlador Upload e para a Action EnviarArquivo que definimos anteriormente.

Estamos usando o atributo multiple em input type o que indica que podemos selecionar mais de um arquivo para enviar.

Para concluir vamos criar a view EnviarArquivo.cshtml, repetindo o procedimento feito anteriormentepara exibir o retorno da operação :

Agora é só alegria...

Antes de executar vamos ajustar o arquivo _Layout.cshtml da pasta /Views/Shared, e, criar um link para acessar a Action Index do controlador Upload, para exibir o formulário de envio de arquivos.

Para isso altere o código que inclui a linha de código destacada conforme abaixo:

Executando o projeto e selecionando alguns arquivos teremos o seguinte resultado:

Verificando a pasta wwwroot do projeto teremos:

Peque o código completo aqui:  Aspn_Upload.zip

(disse Jesus) - 'Porque o coração deste povo está endurecido,E ouviram de mau grado com seus ouvidos,E fecharam seus olhos;Para que não vejam com os olhos,E ouçam com os ouvidos,e compreendam com o coração,e se convertam,e eu os cure.'
Mateus 13:15

 

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti