Upload de arquivos no ASP .NET Core



...

Olá, desenvolvedor! Tudo bem? Estou ótimo, e hoje estou trazendo mais um artigo relacionado a .NET e dessa vez focado em ASP .NET Core.

Neste artigo vou demonstrar uma forma elegante de realizar o upload de arquivos em uma Web API em ASP .NET Core e salvá-los em algum diretório, também vou listar algumas alternativas eficientes para armazenamento de arquivos, vamos lá!

 

 

Let’s Code!

 

Vamos lá então, diferente dos outros artigos, como “upload de imagens” é um objetivo direto, não vou colocar uma descrição sobre “o que é”, podemos partir diretamente para o código.

Primeiramente, crie uma WEB API em .NET Core 2.2 ou superior (utilizarei o .NET 5, mas funciona em versões anteriores).

Comecei criando um controller em branco chamado FileController.cs com o seguinte código:

 

Gostaria de dar destaque ao método upload, que recebe uma lista de IFormFile, ou seja, ele recebe uma lista de arquivos enviados pelo cliente, a biblioteca IFormFile é nativa do ASP .NET.

Show de bola, agora nossa API já recebe os arquivos via requisição, mas aí vem a dúvida, e agora? Como salvá-los em um diretório?

E é exatamente isso que vamos fazer agora! Se você reparar no método upload ainda, eu chamo um _fileService.SaveFiles(files), um serviço para poder salvar esses arquivos em um diretório e esse diretório em uma base de dados (que nesse caso é uma lista estática, mas poderia ser um banco de dados).

Para isso precisamos criar a interface IFileService, seu serviço FileService e também a classe File que servirá de entidade para a base de dados fake.

IFileService.cs

 

FileService.cs

 

File.cs

 

No método SaveFiles, eu recebo uma lista de IFormFile, chamo o método GenerateNewFileName, para gerar um nome para o arquivo que será salvo, logo após chamo GetFileFormat, onde ele realiza um split para poder pegar a extensão do arquivo (.jpeg, .jpg, .png).

Após gerar um novo nome e pegar sua extensão, eu transformo o arquivo (IFormFile) em um array de bytes, chamando o método ConvertFileInByteArray, necessário para salvar o mesmo, logo após chamo CreateFilePath, onde eu pego o caminho físico do diretório que vou salvar esse arquivo.

Note que em CreateFilePath eu chamo o seguinte trecho:

_configuration[“Directories:Files”]

Essa configuração foi colocada no appsettings.json e tem o seguinte valor.

 

Por fim meu chamo o GetFileUrl, para gerar a url de onde o arquivo está hospedado na API e então eu adiciono uma entidade File na nossa base de dados fake.

O método público GetFiles é o mais simples, ele só realiza o retorno das entidades da base de dados fake.

Show de bola, hora de testar, mas antes não se esqueça de adicionar a configuração de injeção de dependência na Startup.cs, no método ConfigureServices.

services.AddScoped();

services.AddSingleton((_) => Configuration);

 

Ah, caso você esteja hospedando na API mesmo e queria disponibilizar esses arquivos pra fontes externas, no método Configure da Startup.cs, adicione o seguinte middleware.

app.UseStaticFiles();

 

Para poder testar eu irei utilizar o Insomnia, mas você pode usar qualquer cliente de requisição http de sua preferência.

Realizei a requisição de upload enviando 2 arquivos de teste, com o body no formato Multipart Form.

 

Se tudo ocorrer bem, na sua API, no diretório wwwroot/images você deve ter algo parecido com isso.

 

Por fim, no método GetFiles, você terá uma resposta parecida com isso.

 

E com isso finalizamos o upload de arquivos!

 

 

Alternativas para salvar arquivos

 

Bom, como eu havia dito na introdução, vou apresentar algumas alternativas para poder salvar os arquivos na aplicação.

No exemplo apresentado os arquivos são armazenados na própria API, o que para cenários simples com pouca quantidade de arquivos é bem eficiente, porém a realidade para cenários maiores com uma quantidade de arquivos exponencial é outra.

Mas não se preocupe, existem alternativas muito eficientes para esse tipo de cenários, a primeira delas é a criação de um CDN (Rede de entrega de conteúdo) no seu servidor.

Uma das diversas vantagens de se utilizar um CDN para armazenamento de arquivos é o desacoplamento entre aplicação e arquivos, visto que agora eles irão ficar em um servidor diferente da aplicação.

OBS: Essa é só uma das funções de se ter o CDN, caso queira saber mais vou deixar um link completo

(https://www.hostinger.com.br/tutoriais/o-que-e-cdn)

 

Uma alternativa bem bacana e a que eu mais gosto é utilizar um serviço de armazenamento de imagens em um provedor de nuvem, como o Azure Storage Blobs ou o AWS S3.

Os mesmos que além de permitir o armazenamento de arquivos em alta escala ainda te disponibiliza segurança, replicação geográfica (ótimo contra latência), suporte a criação de Data Lakes e muitas outras particularidades de cada serviço.

Azure Storage Blobs 

(https://docs.microsoft.com/pt-br/azure/storage/blobs/storage-blobs-introduction)

AWS S3

(https://aws.amazon.com/pt/s3/)

 

Lembrando que essas soluções em nuvem podem ser melhores que a apresentada nesse artigo, PORÉM, elas têm um custo maior e são destinadas a diferentes tamanhos de aplicação.

O que isso significa? Significa que não é necessário utilizar um S3 ou um Storage Blobs em uma aplicação que armazena poucos arquivos e que não tem um tráfego tão grande!

Como desenvolvedor você deve saber analisar o cenário no qual está atuando e aplicar a melhor solução para o problema!

 

 

Conclusão

 

Ufa! O artigo de hoje foi consideravelmente grande, porém aprendemos como realizar o upload de arquivos em APIs construídas em ASP .NET Core 2+, e um segredo que eu não mencionei, funciona também para projetos no formato MVC!

Além disso vimos alternativas eficientes para projetos maiores para realizar o armazenamento desses arquivos, conhecimento necessário quando se trabalha com projetos de grande porte.

Espero que tenha ficado claro a explicação e principalmente a importância de saber analisar o cenário no qual está atuando.

Agradeço a atenção e bons estudos!!!!!

Caso precise entrar em contato, me mande uma mensagem aqui.

Baixe o projeto clicando aqui.