Blazor
- Upload de
arquivos (Static Server) - II
![]() |
Neste artigo veremos como realizar o upload de arquivos no Blazor usando o modo de renderização Static Server Rendering. |
Definindo o menu
Na pasta Components/Layout vamos ajustar o código do arquivo NavMenu para exibir as opções do menu e para acessar os componenes que iremos criar conforme abaixo:
... <div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()"> <nav class="flex-column"> <div class="nav-item px-3"> <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home </NavLink> </div> <div class="nav-item px-3"> <NavLink class="nav-link" href="uploadssr"> <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Uploads </NavLink> </div> <div class="nav-item px-3"> <NavLink class="nav-link" href="exibirarquivos"> <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Ver Arquivos </NavLink> </div> </nav> </div> |
A seguir vamos incluir no arquivo _Imports.razor o código abaixo:
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using BlazorUploads
@using BlazorUploads.Components
@ using Microsoft.AspNetCore.Mvc@using System.Net @using System.ComponentModel.DataAnnotations @inject IWebHostEnvironment env @inject IUploadRepository _repository |
Este código vai permitir compartilhar os recursos usados com todos os componentes do projeto.
Para concluir esta parte, vamos ajustar o código do componente Home.razor conforme o código a seguir:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Upload de arquivos</h1>
<img src="/uploads1.jpg"/>
|
Criando o componente para enviar arquivos
Vamos criar na pasta Components/Pages o componente UploadSSR.razor que vai enviar arquivos para o servidor:
@page "/uploadssr"
@using BlazorUploadSSR.Entities
<div>
<h3>Upload Static Server</h3>
<p>Blazor Server-side Rendering</p>
</div>
@if (Mensagem.Length > 0)
{
<p class="alert alert-secondary" role="alert">@Mensagem</p>
}
<EditForm Model="@Arquivo" OnValidSubmit="@EnviarArquivos" FormName="FormUpload"
method="post" enctype="multipart/form-data">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText class="form-control mb-4" placeholder="Titulo" @bind-Value="@Arquivo.Titulo" />
<InputText class="form-control mb-4" placeholder="Descricao" @bind-Value="@Arquivo.Descricao" />
<InputFile class="form-control mb-4" placeholder="Anexos" name="Arquivo.Anexos" multiple />
<button class="btn btn-primary" type="submit">Enviar Arquivos</button>
</EditForm>
@code {
[SupplyParameterFromForm(FormName = "FormUpload")]
private ArquivoUpload Arquivo { get; set; } = new();
private string Mensagem { get; set; } = String.Empty;
private long tamanhoMaximoArquivo = 1 * 1024 * 1024; //1 MB;
private async Task EnviarArquivos()
{
var extensoesPermitidas = new string[] { ".png", ".jpg", ".jpeg", ".gif" };
Mensagem = "";
if(Arquivo.Anexos.Count <=0 )
{
Mensagem = "Nenhum arquivo selecionado !!!";
return;
}
try
{
foreach (var arquivo in Arquivo.Anexos)
{
string nomeArquivo = WebUtility.HtmlEncode(arquivo.FileName);
var arquivoExtensao = Path.GetExtension(nomeArquivo);
var nomeArquivoSeguro = $"{Guid.NewGuid()}{arquivoExtensao}";
if (!extensoesPermitidas.Contains(arquivoExtensao))
{
Mensagem = $"Arquivo: {nomeArquivo}, é um tipo de Arquivo não permitido";
return;
}
if (arquivo.Length > tamanhoMaximoArquivo)
{
Mensagem = $"Arquivo: {nomeArquivo} excede o tamanho máximo permitido.";
return;
}
var diretorioUpload = Path.Combine(env.WebRootPath, "uploads");
if (!Directory.Exists(diretorioUpload))
{
Directory.CreateDirectory(diretorioUpload);
}
// salva o arquivo localmente
var path = Path.Combine(diretorioUpload, nomeArquivoSeguro);
await using FileStream fs = new(path, FileMode.Create);
await arquivo.CopyToAsync(fs);
// salva imagem no banco de dados
var arquivoDados = new ArquivoDatabase();
arquivoDados.NomeArquivoUpload = nomeArquivoSeguro;
await _repository.UploadArquivoDb(arquivoDados);
}
Arquivo = new();
Mensagem = "Arquivo(s) enviado(s) !!!!";
}
catch (Exception e)
{
Mensagem = "Error: " + e.Message;
}
}
private class ArquivoUpload
{
[Required(ErrorMessage ="O título é obrigatório")]
public string Titulo { get; set; } = String.Empty;
[Required(ErrorMessage = "A descrição é obrigatória")]
public string Descricao { get; set; } = String.Empty;
public IFormFileCollection? Anexos { get; set; }
}
}
|
Vamos entender o código:
A seguir vamos criar o componente ExibirArquivos.razor usando o seguinte código:
@page "/exibirarquivos"
@using BlazorUploadSSR.Entities
@rendermode InteractiveServer
<h3>Arquivos Armazenados</h3>
@if (arquivos != null && arquivos.Any())
{
<div class="file-list">
@foreach (var arquivo in arquivos)
{
<div class="file-item">
<img src="\uploads\@arquivo.NomeArquivoUpload" alt="arquivo" />
<p>@arquivo.NomeArquivoUpload</p>
<button @onclick="() => ExcluirArquivo(arquivo.Id)">Excluir</button>
</div>
}
</div>
}
else
{
<li>Nenhum arquivo encontrado</li>
}
@code {
private IEnumerable<ArquivoDatabase>? arquivos;
protected override async Task OnInitializedAsync()
{
await CarregaImagens();
}
private async Task ExcluirArquivo(int arquivoId)
{
await _repository.DeletaArquivo(arquivoId);
arquivos = await _repository.GetArquivos();
}
private async Task CarregaImagens()
{
arquivos = await _repository.GetArquivos();
}
}
|
Este código exibe os arquivos salvos no banco de dados SQLite e permite excluir os arquivos da tabela sem contudo excluir os arquivos da pasta uploads.
Agora vamos definir um estilo vinculado a este componente criando o arquivo ExibirArquivos.razor.css com este código:
.file-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.file-item {
margin: 5px;
text-align: center;
}
img {
max-width: 120px; /* Tamanho máximo da imagem */
max-height: 120px;
border: 1px solid #ccc;
}
/*.file-item:hover {
transform: scale(3.0);
}*/
|
Executando o projeto teremos o seguinte resultado:
1- Pagina inicial
2- Enviando arquivos
3- Visualizando arquivos
Pegue o código do projeto no github : https://github.com/macoratti/BlazorUpload-Static-Server-Rendering
E estamos conversados...
"Os dias da nossa vida chegam a setenta anos, e se
alguns, pela sua robustez, chegam a oitenta anos, o orgulho deles é canseira e
enfado, pois cedo se corta e vamos voando."
Salmos 90:10
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)