Blazor WebAssembly - Upload de arquivos

Hoje veremos como enviar arquivos para o servidor em uma aplicação Blazor WebAssembly.

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.  

Hoje veremos como enviar arquivos para uma pasta do servidor em um projeto Blazor WebAssembly.

Para isso vamos usar o componente BlazorInputFile que iremos adicionar no projeto via Nuget.

Para saber mais detalhes sobre o componente visite o site : BlazorInputFile Component

Recursos usados:

Criando o projeto no VS Community 2019

bra o VS 2019 Community (versão mínima 16.5) e selecione a opção Create a New Project;

A seguir selecione a opção Blazor app e clique em next;

Informe o nome do projeto :  BlazorWasm_Upload, a localização e clique em Create;

Selecione a opção - Blazor WebAssembly App e marque a opção ASP.NET hosted.

Não vamos usar autenticação e vamos habilitar o https.

Clique no botão Create para criar o projeto.

Com o projeto criado vamos fazer as seguintes alterações, ajustes e configurações :

Exclua os arquivos abaixo e suas referências:

Instale o pacote BlazorInputFile no projeto BlazorWasm_Upload.Client via Gerenciador de Pacotes para a solução:

A seguir no projeto Client abra o arquivo Index.html da pasta wwwroot e inclua o pacote javascript referente ao componente :

...
<body>
    <app>Loading...</app>
    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>
    <script src="_content/BlazorInputFile/inputfile.js"></script>
</body>
...

A seguir inclua no arquivo _Imports.razor do projeto Client o namespace System.IO e o namespace BlazorInputFile :

@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 Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorWasm_Upload.Client
@using BlazorWasm_Upload.Client.Shared
@using System.IO
@using BlazorInputFile

Crie uma pasta images dentro da pasta wwwroot do projeto Client e inclua a imagem upload1.jpg que iremos usar na pagina do componente.

No arquivo NavMenu.razor da pasta Shared do projeto Client, defina apenas um item de menu conforme abaixo:

...
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
       <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Upload de Arquivos
             </NavLink>
   
   </li>
    </ul>
</div>
...

Ajustando o componente Index.razor para enviar arquivo

Abra o arquivo Index.razor substitua o código existente pelo código abaixo:

@page "/"
@inject HttpClient client
<img src="/images/upload1.jpg" />

<h3>Upload de Arquivos</h3>
<div class="card" style="width: 18rem;">
    <div class="card-body">
        <InputFile OnChange="HandleSelection"></InputFile>
    </div>
</div>
<div class="card">
    <div class="card-body">
      <h5>@status</h5>
    </div>
</div>
@code{
        string status;
        async Task HandleSelection(IFileListEntry[] files)
        {
            var file = files.FirstOrDefault();
            if (file != null)
            {
                var ms = new MemoryStream();
                await file.Data.CopyToAsync(ms);
                status = $"Foram enviados {file.Size} bytes do arquivo {file.Name}";
               var content = new MultipartFormDataContent
               {
                   {
                    new ByteArrayContent(ms.GetBuffer()),"\"upload\"",file.Name
                   }
               };
               await client.PostAsync("upload", content);
            }
        }
  }

Neste código usamos o componente para criar um botão para permitir ao usuário selecionar o arquivo a ser enviado e estamos enviando o conteúdo usando o serviço HttpClient para invocar o método Post do controlador UploadController que iremos criar a seguir.

client.PostAsync("upload", content);

Criando o controlador UploadController no projeto Server

Crie um controlador chamado UploadController na pasta Controllers do projeto Server com o código abaixo:

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorWasm_Upload.Server.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class UploadController : ControllerBase
    {
        private readonly IWebHostEnvironment environment;
        public UploadController(IWebHostEnvironment _env)
        {
            environment = _env;
        }
        [HttpPost]
        public async Task Post()
        {
            if(HttpContext.Request.Form.Files.Any())
            {
                foreach(var file in HttpContext.Request.Form.Files)
                {
                    var path = Path.Combine(environment.ContentRootPath, "upload", file.FileName);
                    using(var stream = new FileStream(path,FileMode.Create))
                    {
                        await file.CopyToAsync(stream);
                    }
                }
            }
        }
    }
}

Neste código estamos definindo o método Action Post que vai enviar o arquivo para a pasta upload.

Assim teremos que criar no projeto Server uma pasta chamada upload.

Agora é só alegria...

Executando o projeto teremos o resultado abaixo:

Pegue o projeto aqui:   BlazorWasm_Upload.zip (sem as referências)

(Porque a vida foi manifestada, e nós a vimos, e testificamos dela, e vos anunciamos a vida eterna, que estava com o Pai, e nos foi manifestada);
1 João 1:2

 


Referências:


José Carlos Macoratti