Blazor
- Upload de
arquivos (InteractiveServer) - II
![]() |
Neste artigo veremos como realizar o upload de arquivos no Blazor usando o modo de renderização InteractiveServer. |
Criando o projeto
Vamos criar um novo projeto usando o template Blazor Web App usando o VS 2022 com o nome BlazorUploads :
Definindo as seguintes configurações:
Neste projeto além de enviar arquivos para o servidor vamos também salvar o caminho do arquivo enviado em um banco de dados SQLite.
Para isso vamos incluir no projeto o pacote nuget:
Microsoft.EntityFrameworkCore.Sqlite
Vamos também criar na pasta wwwroot do projeto a pasta uploads para receber os arquivos enviados.
Para representar o arquivo que iremos salvar vamos criar uma pasta Entities e nesta pasta vamos cria a classe ArquivoUpload:
public class ArquivoUpload
{
public int Id { get; set; }
public string? NomeArquivoUpload { get; set; }
}
|
Vamos criar a pasta Context no projeto e nesta pasta criar a classe de contexto AppDbContext:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions options) : base(options)
{ }
public DbSet<ArquivoUpload> ArquivosUploads { get; set; }
}
|
Aqui definimos o mapeamento ORM da entidade para a tabela no SQLite.
A seguir na classe Program vamos registrar o contexto no contêiner DI :
var connectionString = builder.Configuration.GetConnectionString("Sqlite");
builder.Services.AddDbContext<AppDbContext>(opt =>
opt.UseSqlite(connectionString));
|
A string de conexão esta sendo obtida do arquivo appsettings.json:
{
"ConnectionStrings": {
"Sqlite": "data source=ArquivosDB"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
|
O nome do banco a ser criado será ArquivosDB.
Criando o Repositório
Para poder realizar operações com o banco de dados SQLite vamos criar uma pasta Repositories no projeto e nesta pasta vamos criar a interface IUploadRepository e sua implementação que será feita na classe concreta UploadRepository.
Aqui estamos usando o seguinte código:
IUploadRepository
public interface IUploadRepository
{
Task UploadArquivoDb(ArquivoUpload arquivo);
Task<IEnumerable<ArquivoUpload>> GetArquivos();
Task<ArquivoUpload> GetArquivo(int id);
Task DeletaArquivo(int id);
}
|
UploadRepository
public class UploadRepository : IUploadRepository
{
private readonly AppDbContext _context;
public UploadRepository(AppDbContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public async Task UploadArquivoDb(ArquivoUpload arquivo)
{
_context.ArquivosUploads.Add(arquivo);
await _context.SaveChangesAsync();
}
public async Task<IEnumerable<ArquivoUpload>> GetArquivos()
{
return await _context.ArquivosUploads.ToListAsync();
}
public async Task DeletaArquivo(int id)
{
var arquivo = await GetArquivo(id);
if (arquivo is not null)
{
_context.Remove(arquivo);
await _context.SaveChangesAsync();
}
}
public async Task<ArquivoUpload> GetArquivo(int id)
{
var arquivo = await _context.ArquivosUploads.FirstOrDefaultAsync(a => a.Id == id);
return arquivo;
}
}
|
Criando o serviço de Upload
Para realizar o upload de arquivos vamos criar um serviço de upload criando uma pasta Services no projeto e nesta pasta criando a interface IUploadService e UploadService:
IUploadService
public interface IUploadService
{
Task<(int, string)> ArquivoUploadAsync(IBrowserFile arquivo,
int tamanhoMaximoArquivo,
string[] extensoesPermitidas);
}
|
UploadService
public class UploadService : IUploadService
{
private readonly IWebHostEnvironment _environment;
private readonly ILogger<UploadService> logger;
public UploadService(IWebHostEnvironment environment,
ILogger<UploadService> logger)
{
_environment = environment;
this.logger = logger;
}
public async Task<(int, string)> ArquivoUploadAsync(IBrowserFile arquivo,
int tamanhoMaximoPermitido,
string[] extensoesPermitidas)
{
var diretorioUpload = Path.Combine(_environment.WebRootPath, "uploads");
if (!Directory.Exists(diretorioUpload))
{
Directory.CreateDirectory(diretorioUpload);
}
if (arquivo.Size > tamanhoMaximoPermitido)
{
var mensagem = $"Arquivo: {arquivo.Name} excede o tamanho máximo permitido.";
logger.LogInformation(mensagem);
return (0, mensagem);
}
var arquivoExtensao = Path.GetExtension(arquivo.Name);
if (!extensoesPermitidas.Contains(arquivoExtensao))
{
var mensagem = $"Arquivo: {arquivo.Name}, tipo de Arquivo não permitido";
logger.LogInformation(mensagem);
return (0, mensagem);
}
//altera o nome do arquivo
var nomeArquivoSeguro = $"{Guid.NewGuid()}{arquivoExtensao}";
//obtem o caminho do arquivo em wwwroot
var path = Path.Combine(diretorioUpload, nomeArquivoSeguro);
//cria o arquivo
await using var fs = new FileStream(path, FileMode.Create);
// lê e copia paraa memoria
await arquivo.OpenReadStream(tamanhoMaximoPermitido).CopyToAsync(fs);
return (1, nomeArquivoSeguro);
}
}
|
Agora não podemos esquecer de registrar os serviços criados no contêiner DI:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var connectionString = builder.Configuration.GetConnectionString("Sqlite");
builder.Services.AddDbContext<AppDbContext>(opt =>
opt.UseSqlite(connectionString));
builder.Services.AddTransient<IUploadService, UploadService>();
builder.Services.AddTransient<IUploadRepository, UploadRepository>();
var app = builder.Build();
...
app.Run();
|
Para poder criar o banco de dados SQLite sem aplicar o Migrations vamos criar o método CreateDatabase na classe Program:
var builder = WebApplication.CreateBuilder(args);
...
var app = builder.Build();
CreateDatabase(app);
...
app.Run();
static void CreateDatabase(WebApplication app)
{
var serviceScope = app.Services.CreateScope();
var dataContext = serviceScope.ServiceProvider.GetService<AppDbContext>();
dataContext?.Database.EnsureCreated();
}
|
Com isso na primeira execução do projeto, o banco de dados ArquivosDB será criado.
Com isso temos tudo pronto para criar os componentes Blazor para fazer o upload de arquivos e para exibir os nomes e imagens dos arquivos enviados.
No próximo artigo
vamos concluir a implementação....
"(Disse Jesus) Estai em mim, e eu em vós; como a vara de si mesma não pode
dar fruto, se não estiver na videira, assim também vós, se não estiverdes em
mim."
João 15:4
Referências:
C# - Tasks x Threads. Qual a diferença
DateTime - Macoratti.net
Null o que é isso ? - Macoratti.net
Formatação de data e hora para uma cultura ...
C# - Calculando a diferença entre duas datas
NET - Padrão de Projeto - Null Object Pattern
C# - Fundamentos : Definindo DateTime como Null ...
C# - Os tipos Nullable (Tipos Anuláveis)