Hoje veremos como enviar arquivos para o servidor em uma aplicação Blazor Server usando o componente InputFile. |
Se você esta chegando agora e não sabe o que é o Blazor leia o artigo ASP .NET Core - Iniciando com o Blazor - Macoratti; se você já conhece e quer saber mais pode fazer o curso de Blazor Essencial.
Eu já mostrei como enviar arquivos no Blazor usando o componente BlazorInputFile que não era um componente nativo do Blazor. A partir do .NET 5, o Blazor apresenta o componente nativo InputFile que pode ser usado para ler dados de arquivos via navegador tanto no Blazor Server como no Blazor WebAssembly.
O componente InputFile renderiza um elemento HTML <input> do tipo file. Por padrão, o usuário seleciona arquivos individuais,e , para permitir que o usuário carregue vários arquivos ao mesmo tempo basta adicionar o atributo multiple.
Exemplo:
<InputFile OnChange="@CarregaArquivos" multiple />
@code { |
No código acima o componente executa o método CarregaArquivos quando o evento OnChange ocorrer.
Vejamos a seguir como fazer isso na prática.
Recursos usados:
Blazor Server - Usando InputFile
Abra o VS 2022 Community e selecione a opção Create a New Project;
A seguir selecione a opção Blazor Server App e clique em next;
Informe o nome do projeto : BlazorServerUpload;
A seguir define as configurações conforme a figura abaixo e clique em Create;
Com o projeto criado vamos fazer as seguintes alterações, ajustes e configurações :
Exclua os arquivos abaixo e suas referências:
No arquivo _Imports.razor vamos incluir uma referência a : 1-Microsoft.AspNetCore.Components.Forms e 2-System.IO
@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using BlazorServerUpload @using BlazorServerUpload.Shared @using System.IO |
O primeiro permite acesso ao componente InptuFile e o seguinte permite criar e escrever em arquivos no servidor.
No arquivo NavMenu.razor da pasta Shared inclua mais um item de menu para exibir a opção Upload:
... <div class="@NavMenuCssClass" @onclick="ToggleNavMenu"> <ul class="nav flex-column"> <li class="nav-item px-3"> <NavLink class="nav-link" href="/fileupload"> <span class="oi oi-cloud-upload" aria-hidden="true"></span> Upload </NavLink> </li> </ul> </div> ... |
Crie uma pasta images dentro de wwwroot e inclua nesta pasta a imagem upload1.jpg que iremos usar no projeto.
A seguir altere o código do arquivo Index.razor para:
@page "/" <PageTitle>Index</PageTitle> <img src="/images/upload1.jpg" /> <h3>Blazor Server - InputFile</h3> |
A seguir vamos criar um novo componente chamado FileUpload na pasta Pages do projeto e incluir o código abaixo neste arquivo:
@page "/fileupload" @inject IWebHostEnvironment environment @inject ILogger<FileUpload> Logger <h1>Blazor Server File Upload</h1> <h5>@Message</h5> <form
@onsubmit="OnSubmit"> @code
{
private void OnInputFileChange(InputFileChangeEventArgs
e)
private async void OnSubmit() |
Vamos entender o código :
1- Injetamos uma instância de IWebHostEnvironment para descobrir o caminho de wwwroot no servidor para salvar os arquivos carregados; O ILogger é usado para logar os erros ocorridos;
@inject IWebHostEnvironment
environment
@inject ILogger<FileUpload>
Logger
2- A propriedade Message apenas exibe mensagens:
<h5>@Message</h5>
3- Criamos um formulário que será submetido no evento OnSubmit onde estamos usando o componente InputFile usando o atributo multiple que permite selecionar mais de um arquivo, e que define o método OnInputFileChange onde vamos tratar a exibição de quantos arquivos foram selecionados.
<form @onsubmit="OnSubmit">
<InputFile OnChange="OnInputFileChange"
multiple />
<br /><br />
<button type="submit">Enviar Arquivo(s) selecionado(s) para
Upload</button>
</form>
O botão Enviar apenas submete o formulário.
No bloco de código do arquivo temos:
4- A definição do texto da mensagem inicial e a definição da variável arquivoSelecionados como sendo uma lista somente leitura do tipo IBrowserFile que representa os dados de um arquivo selecionado pelo InputFile :
string Message =
"Nenhum arquivo selecionado";
IReadOnlyList<IBrowserFile>? arquivoSelecionados = null;
5- O método OnInputFileChange trata o evento OnChange do componente InputFile e obtém a lista de arquivos selecionados alterando o texto da mensagem:
private
void OnInputFileChange(InputFileChangeEventArgs
e)
{
arquivoSelecionados = e.GetMultipleFiles();
Message = $"{arquivoSelecionados.Count}
arquivo(s) selecionado(s)";
}
6- No método assíncrono OnSubmit estamos tratando o envio do formulário.
Primeiro
verificamos se existem arquivos selecionados para a seguir percorrer a lista de
arquivos usando um bloco foreach e ler cada arquivo
e a seguir usamos o método OpenReadStream() para
abrir um fluxo através do qual o conteúdo do arquivo carregado pode ser lido.
Lembre-se de que este é um aplicativo Blazor Server e seu código está sendo
executado no lado do servidor. Portanto, combinamos as propriedades
WebRootPath e Name do
objeto IBrowserFile para chegar ao caminho final do
lado do servidor para o arquivo.
Como queremos salvar o arquivo carregado no servidor, criamos um novo
FileStream para o arquivo. Em seguida, copiamos o
conteúdo do arquivo para o FileStream usando o
método CopyToAsync(). Por fim, fechamos os dois
fluxos. Aqui, estamos fazendo tratamento de erros básico mas não estamos
verificando o tamanho do arquivo, o que deve ser considerado em uma aplicação de
produção:
private async void OnSubmit() { if (arquivoSelecionados is not null) { foreach (var file in arquivoSelecionados) { try { Stream stream = file.OpenReadStream(); var path = $"{environment.WebRootPath}\\Uploads\\{file.Name}"; FileStream fs = File.Create(path); await stream.CopyToAsync(fs); stream.Close(); fs.Close(); Message = $" Enviar {arquivoSelecionados.Count} arquivo(s) enviado(s) para o servidor"; } catch (Exception ex) { Message = $"Erro ao enviar arquivo : {file.Name} : {ex.Message}"; Logger.LogError("File: {Filename} Error: {Error}", file.Name, ex.Message); } } } else { Message = $"Selecione um arquivo ..."; } } |
Atenção !!! Os arquivos enviados estão sendo salvos na pasta Uploads que deverá ser criada dentro da pasta wwwroot.
Agora é só alegria...
Executando o projeto teremos o resultado abaixo:
Em outro artigo veremos como fazer a mesma coisa em um projeto Blazor WebAssembly.
Pegue o projeto aqui: BlazorServerUpload.zip (sem as referências)
"Bom é ter esperança, e aguardar em
silêncio a salvação do Senhor."
Lamentações 3:26
ASP .NET Core - Iniciando com o Blazor
ASP .NET Core - CRUD usando Blazor e Entity ..
Blazor - O novo framework SPA da Microsoft
Visual Studio Code - Suporte ao desenvolvimento Blazor
Vale a pena usar o Blazor
Blazor - Usando o recurso da Virtualização (.NET 5)
Blazor - Conceitos, dicas e truques valiosos - I