DEV Community

Cover image for [PT-Br] Conheça o Blazor e o poder do WebAssembly
João Paulo de C. Lima
João Paulo de C. Lima

Posted on • Edited on

4 2

[PT-Br] Conheça o Blazor e o poder do WebAssembly

Overview

O que é Blazor?

É um framework para aplicações “client-side” escrito em .NET e rodando em cima do WebAssembly.
É baseado em tecnologias já existentes como HTLM e CSS, mas você pode usar C# e Razor ao invés de Javascript para buildar os componentes. Oferece todos os benefícios de uma plataforma de aplicativo de página única (SPA) rica e moderna ao usar o .NET de ponta a ponta.
A ideia sobre o Blazor é ser capaz de combinar Razor e C # em um projeto da web do lado do cliente que roda completamente no navegador.

WebAssembly

WebAssembly é um formato binário para o código no navegador e é executado muito mais rápido do que o JavaScript tradicional. Oferece ao navegador várias vantagens, como:

  1. Executa em desempenho quase nativo
  2. É executado em uma caixa de areia segura para a memória
  3. Compila a partir de uma variedade de linguagens, ou seja, .NET, C, C ++, Java, Rust, etc.

A principal vantagem do WebAssembly é que ele lida muito bem com trabalhos com muita memória e multithreading, em comparação com o javascript.

Features

O Blazor contém todos os recursos de uma estrutura web moderna, como:

  • Um modelo de componente para a construção de IU combinável
  • Roteamento
  • Layouts
  • Formulários e validação
  • Injeção de dependência
  • Recarregamento ao vivo no navegador durante o desenvolvimento
  • Renderização do lado do servidor
  • Depuração completa do .NET em navegadores e no IDE
  • Rich IntelliSense e ferramentas
  • Publicação e corte de tamanho de aplicativo

Setup

  1. Baixe e instale o .NET Core 2.1 SDK (2.1.300 ou posterior).
  2. Baixe e instale o Visual Studio 2017 (15.7 ou posterior) com o ASP.NET e a carga de trabalho de desenvolvimento da web selecionados.

Fonte: link

Um CRUD simples utilizando Blazor, EFCore e InMemoryDatabase

Neste exemplo vou lhes mostrar como fazer um simples CRUD utilizando as seguintes ferramentas:

Após a instalação do Blazor, vamos criar um projeto através do seguinte comando:

dotnet new blazorserver -o <VOCE_ESCOLHE_O_NOME> --no-https
Enter fullscreen mode Exit fullscreen mode
cd NOME_QUE_VOCE_ESCOLHEU
Enter fullscreen mode Exit fullscreen mode

Observação: você pode utilizar o Visual Studio e criar o projeto através do caminho “File > New Solution” e pesquisar por “Blazor”

Para saber se está tudo OK, basta digitar o comando

dotnet run
Enter fullscreen mode Exit fullscreen mode

Por padrão, já vem criada uma aplicação para você se ambientar com o Blazor. Para visualizar a aplicação, acesse http://localhost:5000

Agora, vamos criar as nossas classes, páginas e instalar alguns pacotes necessários para fazermos o CRUD.

Setup:

Primeiro, vamos instalar o pacote Microsoft.EntityFrameworkCore.InMemory. Para isso, digite o seguinte comando (dentro da pasta do seu projeto):

dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 3.1.8
Enter fullscreen mode Exit fullscreen mode

Codificando

Agora, dentro da pasta “Data”, vamos criar as seguintes classes: “Context.cs” e “ClienteService.cs”.

Imagem 1

A classe “ClienteService.cs” terá o seguinte código:

using Blazor.Client.Data;
using Blazor.Client.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Blazor.Data
{
public class ClienteService
{
readonly Context _context = new Context();
/// <summary>
/// Add cliente to the memory database
/// </summary>
/// <param name="cliente">The Cliente object</param>
public async Task AddAsync(Cliente cliente)
{
await Task.Run(() => _context.Clientes.Add(cliente));
SaveChanges();
}
/// <summary>
/// Add cliente to the memory database
/// </summary>
/// <param name="cliente">The Cliente object</param>
public void Add(Cliente cliente)
{
_context.Clientes.Add(cliente);
SaveChanges();
}
/// <summary>
/// Get all Clientes from memory database
/// </summary>
/// <returns>A list of all Clientes</returns>
public async Task<IEnumerable<Cliente>> GetAllAsync()
{
List<Cliente> retorno;
return await Task.Run(() => retorno = new List<Cliente>(_context.Clientes));
}
/// <summary>
/// Get all Clientes from memory database
/// </summary>
/// <returns>A list of all Clientes</returns>
public IEnumerable<Cliente> GetAll()
{
List<Cliente> retorno = new List<Cliente>(_context.Clientes);
return retorno;
}
/// <summary>
/// Get the Cliente by its ID
/// </summary>
/// <param name="id">An integer ID</param>
/// <returns></returns>
public Cliente GetById(int id)
{
var query = _context.Clientes.Find(id);
return query;
}
/// <summary>
/// Get the Cliente by its ID
/// </summary>
/// <param name="id">An integer ID</param>
/// <returns></returns>
public async Task<Cliente> GetByIdAsync(int id)
{
Cliente cliente;
return await Task.Run(() => cliente = _context.Clientes.Find(id));
}
/// <summary>
/// Update the Cliente on memory database
/// </summary>
/// <param name="cliente">The Cliente object</param>
public void Update(Cliente cliente)
{
_context.Clientes.Update(cliente);
SaveChanges();
}
/// <summary>
/// Update the Cliente on memory database
/// </summary>
/// <param name="cliente">The Cliente object</param>
public async Task UpdateAsync(Cliente cliente)
{
await Task.Run(() => _context.Clientes.Update(cliente));
SaveChanges();
}
/// <summary>
/// Delete the Client on memory database
/// </summary>
/// <param name="cliente">The Cliente object</param>
public void Delete(Cliente cliente)
{
_context.Clientes.Remove(cliente);
SaveChanges();
}
/// <summary>
/// Delete the Client on memory database
/// </summary>
/// <param name="cliente">The Cliente object</param>
public async Task DeleteAsync(Cliente cliente)
{
await Task.Run(() => _context.Clientes.Remove(cliente));
SaveChanges();
}
private int SaveChanges()
{
return _context.SaveChanges();
}
}
}

A classe “Context.cs” terá o seguinte código:

using Blazor.Client.Models;
using Microsoft.EntityFrameworkCore;
namespace Blazor.Client.Data
{
public class Context : DbContext
{
public DbSet<Cliente> Clientes { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseInMemoryDatabase("BlazorDB");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Cliente>()
.HasKey(c => c.Id);
}
}
}
view raw Context.cs hosted with ❤ by GitHub

Agora, dentro da pasta “Models”, vamos criar a seguinte classe:
Imagem 2

A classe “Model.cs” terá o seguinte código:

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Blazor.Client.Models
{
public class Cliente
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required(ErrorMessage = "Por favor, preencha o nome!")]
[StringLength(60, MinimumLength = 4,
ErrorMessage = "O nome deve ter no minimo 4 e no maximo 60 caracteres!")]
[DisplayName("Nome")]
public string Nome { get; set; }
[Required(ErrorMessage = "Por favor, preencha o RG!")]
[StringLength(9)]
[DisplayName("RG")]
public string Rg { get; set; }
[Required(ErrorMessage = "Por favor, preencha o CPF!")]
[StringLength(11, ErrorMessage = "O CPF deve conter 11 digitos")]
[DisplayName("CPF")]
public string Cpf { get; set; }
[Required(ErrorMessage = "Por favor, preencha o Endereco!")]
[StringLength(60)]
[DisplayName("Endereco")]
public string Endereco { get; set; }
[Required(ErrorMessage = "Por favor, preencha o Telefone!")]
[StringLength(11)]
[DisplayName("Telefone")]
public string Telefone { get; set; }
[Required(ErrorMessage = "Por favor, preencha o Celular!")]
[StringLength(12)]
[DisplayName("Celular")]
public string Celular { get; set; }
[Required(ErrorMessage = "Por favor, preencha o email!")]
[EmailAddress(ErrorMessage = "Email invalido!")]
[StringLength(60)]
[DisplayName("Email")]
public string Email { get; set; }
}
}
view raw Model.cs hosted with ❤ by GitHub

Agora, dentro da pasta “Pages”, vamos criar a pasta “Clientes” e dentro dela as seguintes páginas: “Cadastrar.razor” e “Editar.razor”.
Ainda na pasta “Pages”, vamos criar a página “Cliente.razor”.
Imagem 3

A página “Cadastrar.razor” terá o seguinte código:

@page "/Clientes/cadastrar"
@using Blazor.Data
@using Models = Blazor.Client.Models
@inject ClienteService Service
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
<h3>Cadastrar Clientes</h3>
<div class="container">
<h1 class="text-center">Cadastro de Clientes</h1>
<div class="row" style="padding-top: 10%">
<div class="col-lg-12">
<div class="form-group-lg">
<EditForm class="text-center" Model="@_cliente">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="row">
<div class="col-lg-6">
<label id="Nome"> Nome:</label>
<InputText id="Nome" @bind-Value="@_cliente.Nome" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<label id="Rg">RG:</label>
<InputText id="Rg" @bind-Value="@_cliente.Rg" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label id="Cpf">CPF:</label>
<InputText id="Cpf" @bind-Value="@_cliente.Cpf" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<label id="Endereco">Endereço:</label>
<InputText id="Endereco" @bind-Value="@_cliente.Endereco" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label id="Telefone">Telefone:</label>
<InputText id="Telefone" @bind-Value="@_cliente.Telefone" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<label id="Celular">Celular:</label>
<InputText id="Celular" @bind-Value="@_cliente.Celular" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label id="Email">E-mail:</label>
<InputText id="Email" @bind-Value="@_cliente.Email" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<br />
<br />
<input type="submit" value="Cadastrar" class="btn btn-primary" @onclick="OpenModal" />
</div>
</div>
</EditForm>
</div>
</div>
</div>
</div>
@code {
private Models.Cliente _cliente = new Models.Cliente();
private int idCount = 0;
/// <summary>
/// It opens the JS alert with a message
/// </summary>
/// <returns>void</returns>
public async Task OpenModal()
{
await JSRuntime.InvokeAsync<string>(
"jsFunctions.openModalCadastro", null);
AddCliente();
}
private void AddCliente()
{
_cliente.Id = idCount++;
Service.Add(_cliente);
NavigationManager.NavigateTo("cliente");
}
}
view raw Cadastrar.razor hosted with ❤ by GitHub

E a página “Editar.razor” terá o seguinte código:

@page "/Clientes/editar/{Id:int}"
@using Blazor.Data
@using Models = Blazor.Client.Models
@inject ClienteService Service
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
<h3>Cadastrar Clientes</h3>
<div class="container">
<h1 class="text-center">Cadastro de Clientes</h1>
<div class="row" style="padding-top: 10%">
<div class="col-lg-12">
<div class="form-group-lg">
<EditForm class="text-center" Model="@_cliente">
<div class="row">
<div class="col-lg-6">
<label id="Nome"> Nome:</label>
<InputText id="Nome" @bind-Value="@_cliente.Nome" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<label id="Rg">RG:</label>
<InputText id="Rg" @bind-Value="@_cliente.Rg" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label id="Cpf">CPF:</label>
<InputText id="Cpf" @bind-Value="@_cliente.Cpf" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<label id="Endereco">Endereço:</label>
<InputText id="Endereco" @bind-Value="@_cliente.Endereco" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label id="Telefone">Telefone:</label>
<InputText id="Telefone" @bind-Value="@_cliente.Telefone" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<label id="Celular">Celular:</label>
<InputText id="Celular" @bind-Value="@_cliente.Celular" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label id="Email">E-mail:</label>
<InputText id="Email" @bind-Value="@_cliente.Email" class="form-control" />
<span class="text-danger" style="font-size:small;"></span>
</div>
<div class="col-lg-6">
<br />
<br />
<input type="submit" value="Editar" class="btn btn-primary" @onclick="OpenModal" />
</div>
</div>
</EditForm>
</div>
</div>
</div>
</div>
@code {
private Models.Cliente _cliente;
[Parameter]
public int Id { get; set; }
protected override async Task OnInitializedAsync()
{
_cliente = Service.GetById(Id);
}
public async Task OpenModal()
{
await JSRuntime.InvokeAsync<string>(
"jsFunctions.openModalEdit", null);
EditarCliente();
}
private void EditarCliente()
{
Service.Update(_cliente);
NavigationManager.NavigateTo("cliente");
}
}
view raw Editar.razor hosted with ❤ by GitHub

Repare que em ambas as páginas temos códigos C# escritos dentro do bloco “@code”. Dentro desse bloco é possível criar qualquer código em C#.

Testando

Após realizar a codificação, rode o comando “dotnet build” para buildar a aplicação. Caso apareça algum erro, leia-o atentamente e verifique os passos anteriores deste artigo.

Deu tudo certo? Então, vamos rodar nossa aplicação:
dotnet run

Essa é a nossa página inicial:
Imagem 4

Você pode navegar pelas páginas através do menu no lado esquerdo.

Nossa págna “Cliente” está vazia:
Imagem 5

Vamos cadastrar alguns clientes:
Imagem 6
Imagem 7
Imagem 8

Agora, nossa página de “Clientes” foi preenchida:
Imagem 9
Repare que podemos editar e excluir o dado cadastrado.
Vamos, primeiro, editar:
Imagem 10
Imagem 11
Imagem 12

Agora, vamos excluí-lo:
Imagem 13
Imagem 14

We made it!

Todas as funções desse CRUD estão na classe “ClienteService.cs”. Lembra do bloco “@code” dentro das páginas “.razor”? Pois bem, é nesse bloco que chamamos as funções da nossa classe.

Este foi um pequeno exemplo de como utilizar o C# com WebAssembly através do Blazor. Espero que tenham gostado.
Qualquer dúvida, crítica ou sugestão deixe nos comentários.

Còdigo no Github: source code

Um grande abraço!

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay