ASP.NET Core - Enviando Arquivos para um API
Neste artigo vamos recordar como enviar um arquivo para uma API usando o HttpClient. |
Hoje veremos como enviar arquivos para uma Web API que ao receber os arquivos vai salvar estes arquivos na pasta wwwroot do projeto no servidor.
recursos usados:
Criando o projeto Web API
Vamos criar um novo projeto ASP .NET Core Web API chamado ApiArquivos usando o .NET 6.
Vamos remover o controlador e a classe usada pelo controlador criado pelo template e criar no projeto a pasta wwwroot.
A seguir crie no projeto a pasta Services e nesta pasta crie a classe SalvarArquivosApi:
public class SalvaArquivosApi
{
private readonly IWebHostEnvironment env;
public SalvaArquivosApi(IWebHostEnvironment env)
{
this.env = env;
}
public async Task Salvar(IFormFile arquivo, string nomePasta)
{
var nomeArquivo = $"{Guid.NewGuid()}{Path.GetExtension(arquivo.FileName)}";
string caminhoArquivoServidor = Path.Combine(env.WebRootPath, nomePasta);
if (!Directory.Exists(nomePasta))
{
Directory.CreateDirectory(nomePasta);
}
string caminhoArquivo = Path.Combine(caminhoArquivoServidor, nomeArquivo);
using (FileStream fileStream = File.Create(caminhoArquivo))
{
await arquivo.OpenReadStream().CopyToAsync(fileStream);
}
}
}
|
Neste código injetamos uma instância de IWebHostEnvironment no construtor da classe SalvarArquivosApi para obter acesso ao caminho da pasta wwwroot usando a propriedade WebRootPath.
Vamos gerar um nome de arquivo aleatório usando a struct Guid eo método NewGuid com a extensão do arquivo.
Se a pasta informada em nomePasta não existir será criada a pasta usando o método CreateDirectory.
A seguir montamos o caminho completo do arquivo com nome e criamos o arquivo na pasta.
Precisamos agora registrar este serviço no container DI pois vamos injetar o serviço no controlador. Para isso na classe Program vamos definir o código :
... builder.Services.AddTransient<SalvaArquivosApi>(); var app = builder.Build();... |
Criando o controlador ArquivosController
Na pasta Controller do projeto vamos criar o controlador ArquivosController com o código abaixo:
using ApiArquivos.Services;
using Microsoft.AspNetCore.Mvc;
namespace ApiArquivos.Controllers;
[Route("api/[controller]")]
[ApiController]
public class ArquivosController : ControllerBase
{
private readonly SalvaArquivosApi salvarArquivoApi;
public ArquivosController(SalvaArquivosApi salvarArquivoApi)
{
this.salvarArquivoApi = salvarArquivoApi;
}
[HttpGet]
public ActionResult<string> Get()
{
return $"Endpoint acessado em {DateTime.Now.ToShortDateString()}";
}
[HttpPost()]
public async Task<IActionResult> Post([FromForm] IFormFile arquivo)
{
try
{
await salvarArquivoApi.Salvar(arquivo, "arquivos");
return Ok();
}
catch (Exception ex)
{
var erro = ex.Message;
var result = StatusCodes.Status500InternalServerError.ToString(erro);
throw;
}
}
}
|
Criamos dois endpoints um Get apenas para testar a API e o outro Post que vai receber o arquivo enviado via request.
No método Post usamos o tipo o atributo [FromForm] que obtém valores de campos de formulário postados.
Definimos também o tipo IFormFile que representa os arquivos transmitidos em uma solicitação HTTP. A interface nos dá acesso a metadados como ContentDisposition, ContentType, Length, FileName e muito mais. IFormFile também fornece alguns métodos usados para armazenar arquivos.
A seguir usamos o método Salvar do nosso serviço para salvar o arquivo na pasta.
Criando o projeto Console para enviar o arquivo
Vamos incluir um projeto do tipo Console via menu File->Add-> New Project com o nome EnviaArquivoApi.
Na classe Program deste projeto inclua a código abaixo:
Console.WriteLine("## Envia arquivos para Web API ##\n");
string baseUrl = "http://localhost:5075/api/arquivos";
Console.WriteLine("Informe a pasta do arquivo\t");
var pathArquivo = Console.ReadLine();
if (string.IsNullOrEmpty(pathArquivo))
{
Console.WriteLine("\nNome inválido");
return;
}
Console.WriteLine("Informe o nome do arquivo\t");
var nomeArquivo = Console.ReadLine();
if (string.IsNullOrEmpty(nomeArquivo))
{
Console.WriteLine("\nArquivo inválido");
return;
}
var resultado = await EnviarArquivo(pathArquivo, nomeArquivo, baseUrl);
Console.WriteLine(resultado);
Console.ReadKey();
static async Task<string> EnviarArquivo(string caminho, string arquivo, string baseUrl)
{
HttpClient httpClient = new HttpClient();
var arquivoCompleto = Path.Combine(caminho, arquivo);
var nomeArquivo = Path.GetFileName(arquivoCompleto);
using var requestContent = new MultipartFormDataContent();
using var fileStream = File.OpenRead(arquivoCompleto);
requestContent.Add(new StreamContent(fileStream), "arquivo", nomeArquivo);
var response = await httpClient.PostAsync(baseUrl, requestContent);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
|
No código acima estamos informando o diretório e o nome do arquivo que desejamos enviar.
A seguir no método EnviarArquivo estamos usando uma instância de HttpClient e o método PostAsync para enviar o conteúdo informado para a uri de atendendimento da nossa api definida em baseUrl.
Para testar vamos enviar o arquivos filmes.csv que esta na pasta d:\dados para o servidor.
Executando o projeto teremos a API em atendimento e projeto Console sendo executado:
O projeto Console onde informamos a pasta e nome do arquivo:
Após o processamento teremos o arquivo salvo na pasta wwwroot/arquivos com o nome aleatório gerado e podemos visualizar o conteúdo do arquivo visto que é um arquivo csv :
E estamos conversados...
Pegue o projeto aqui: ApiArquivos.zip
"Porque nele(Jesus) foram criadas todas as coisas
que há nos céus e na terra, visíveis e invisíveis, sejam tronos, sejam
dominações, sejam principados, sejam potestades. Tudo foi criado por ele e para
ele."
Colossenses 1:16
Referências:
Curso Fundamentos da Programação Orientada a Objetos com VB .NET