Blazor - Criando uma SPA Blazor com VS Code
Hoje vamos criar uma aplicação SPA a partir de uma projeto ASP .NET Core vazio usando os recursos do Blazor. |
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 meu curso de Blazor Essencial.
Como a versão WebAssembly ja esta esta liberada para produção é bom você atualizar os templates emitindo o comando abaixo em uma janela de comandos:
dotnet new --install Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.1
Você pode encontrar documentos e exemplos adicionais em https://blazor.net.
Criando uma aplicação SPA Blazor Server
Vamos iniciar criando uma aplicação SPA a partir de um projeto ASP .NET Core usando o template Empty.
Abra um terminal de linha de comandos, e digite o comando : dotnet new web -o contador
Isso vai criar um projeto ASP .NET Core Web vazio na dentro da pasta contador:
Para abrir no VS Code basta entrar na pasta contador e digitar: code .
Vamos criar uma aplicação SPA e para isso teremos que configurar o projeto usando os recursos do Blazor. Para começar vamos definir o tipo de projeto como Blazor Server.
No Blazor Server, a construção da interface do usuário no lado do servidor é feita com base no Razor Pages, uma abordagem alternativa fornecida pela Microsoft para o padrão MVC. Ela é baseado no conceito de páginas em vez de controladores e views.
Assim vamos começar definindo no método ConfigureServices do arquivo Startup.cs, a carga da configuração do Razor Pages e Blazor Server.
Teremos também que dar suporte aos arquivos estáticos, aos endpoints e ao fallback para a página no método Configure().
Para isso vamos ter que alterar o código existente nos métodos ConfigureServices() e Configure() conforme abaixo:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
namespace contador
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}
|
A palavra Hub no endpoints.MapBlazorHub() deve ser familiar se você já sabe como o SignalR funciona.
O código endpoints.MapFallbackToPage("/_Host") configuram a página para navegar se o recurso especificado não for encontrado e também definir a página padrão para nosso aplicativo.
Precisamos criar um arquivo chamado _Host. cshtml em uma pasta chamada Pages. A pasta Pages é obrigatória por padrão, porque o mecanismo Razor Pages procura por páginas nesse local.
Vamos então criar uma pasta Pages na raiz do projeto e nesta pasta criar o arquivo _Host.cshtml que vai conter o HTML base da aplicação e o código para renderização do componente Blazor:
@page "/"
@namespace contador.Pages
<!DOCTYPE html>
<html lang="en">
<head>
<title>Contador</title>
</head>
<body>
@(await Html.RenderComponentAsync<Contador>(RenderMode.ServerPrerendered))
<script src="_framework/blazor.server.js"></script>
</body>
</html>
|
O Blazor usa o mesmo conceito de componente que todas os frameworks UI modernos , nas quais um conjunto de peças, chamado componentes Blazor, compõe a interface do usuário como em um quebra-cabeça. Um componente Blazor é, portanto, um parte reutilizável da interface do usuário que pode conter HTML e código C# e outros componentes do Blazor.
O método RenderComponentAsync() renderiza o componente indicado em seu parâmetro genérico (Contador) com um servidor na modalidade pré-renderizado. Esse método de renderização de um componente é uma peculiaridade do Blazor Server e não é usado, por exemplo, no Blazor WebAssembly.
O script
_framework/blazor.server.js carrega o código
JavaScript do Blazor que permite a comunicação com o servidor. Observe que para
permitir o carregamento do script, precisamos habilitar o método
app.UseStaticFiles()
na classe Startup.
Vamos criar agora o componente Blazor Contador.razor na pasta raiz.
Nosso objetivo é criar um componente que implementa uma contagem regressiva simples de 10 a 0 quando o usuário clica em um Botão.
Vamos começar definindo a interface do usuário e inicializando a contagem regressiva quando alguém clicar no botão Iniciar:
@using Microsoft.AspNetCore.Components.Web
<h1>Contador Blazor</h1>
<p>@contar</p>
<button @onclick="IniciaContagem">Iniciar</button>
@code {
private int contar = 0;
private void IniciaContagem()
{
contar = 10;
}
}
|
Vamos entender o código acima:
- A diretiva @page indica o caminho no qual esse componente responde;
- A instrução using carrega os elementos do Blazor;
- A marcação define sua interface: um título, um parágrafo e um botão. É um HTML simples com algumas instruções do Razor.
- A instrução @contar grava o valor da variável contar. O framework atualiza o valor no parágrafo para você quando ela mudar.
- Quando o usuário
clicar no botão Iniciar, o método IniciaContagem()
será chamado graças à declaração:
@onclick = "IniciaContagem" declaração.
- O bloco @code permite definir o código C# do
componente. Um arquivo Razor é uma classe C# , para que você possa criar
atributos e métodos para gerenciar o status do seu componente.
- O código define o valor 10 para contar quando o método IniciaContagem() for invocado.
Para implementar uma contagem regressiva, precisamos adicionar um timer que diminui a contagem para 0. Vamos alterar o bloco @code incluindo o código a seguir:
@using Microsoft.AspNetCore.Components.Web
@using System.Timers;
<h1>Contador Blazor</h1>
<p>@contar</p>
<button @onclick="IniciaContagem">Iniciar</button>
@code {
private int contar = 0;
private void IniciaContagem()
{
contar = 10;
Timer timer = new Timer (1000);
timer.Elapsed += (source, e) =>
{
contar--;
InvokeAsync(() => StateHasChanged());
if (contar == 0) timer.Stop ();
};
timer.Start ();
}
}
|
Criamos um objeto Timer simples que executa o retorno de chamada inscrito ao evento Elapsed a cada segundo (você precisa adicionar a instrução @using System.Timers na parte superior da página para usar a classe Timer).
É simples, mas não
funciona porque o código no retorno de chamada é executado em um thread
separada e, quando a variável contar diminuir, a
alteração não será detectada pelo framework Blazor.
Para resolver esse problema temos que alertar manualmente o framework que o
estado do componente foi modificado, chamando o método
StateHasChanged(), e, como esse método tem que ser chamado a partir da
mesma thread da interface do usuário usamos o método
InvokeAsync().
Executando o projeto iremos obter o seguinte resultado:
Temos assim uma aplicação SPA usando o Blazor Server a partir de um projeto ASP
.NET Core.
Quando rodamos o projeto o HTML é renderizado no lado do servidor e o script blazor.server.js é baixado e executado no navegador.
O script começa a conexão com a API SignalR Hubs e abre um WebSocket a partir do servidor para o cliente. O SignalR é uma biblioteca da Microsoft que permite que os dados sejam enviados do servidor para o cliente usando o canal de melhor desempenho disponível.
Quando o
carregamento da página é concluído, a biblioteca cliente inicia a negociação com
o servidor para escolher o melhor tipo de comunicação. Se disponível, a primeira
opção é o uso do WebSocket, um protocolo padrão
(RFC 6455,
padronizado para navegadores da Web pelo W3C) que fornece um modo
full-duplex canal de comunicação através de uma única comunicação TCP.
Após uma primeira resposta HTTP do tipo text/event-stream, o servidor pode enviar dados que o cliente pode receber com um simples retorno de chamada no Objeto EventSource.
O Blazor Server usa o SignalR para enviar a atualização da interface do usuário para o cliente. Quando o usuário clica no botão, uma mensagem é enviada ao servidor que executa a solicitação e envia ao navegador as alterações a serem aplicadas ao DOM do navegador. As próximas mensagens são causadas pelo timer que a cada segundo atualiza o contador. O contador regressivo é uma thread do servidor que atualiza a variável contar e quando o mecanismo Blazor detecta um mudança e atualiza a interface do cliente através do SignalR.
No próximo artigo veremos como criar uma aplicação SPA a partir de uma aplicação ASP .NET Core usando o Blazor WebAssembly.
Pegue o projeto aqui : contador_blazor.zip
"Se o mundo vos
odeia, sabei que, primeiro do que a vós, me odiou a mim.
Se vós fôsseis do mundo, o mundo amaria o que era seu, mas porque não sois do
mundo, antes eu vos escolhi do mundo, por isso é que o mundo vos odeia."
João 15:18,19
Referências:
C# - StreamReader, StringReader e TextReader . Qual a ... - Macoratti
C# - Imprimindo um arquivo texto - Macoratti
ASP .NET Core Blazor - Macoratti.net
ASP .NET Core - Iniciando com Blazor - Macoratti.net
Blazor - Vale a pena usar o Blazor - Macoratti.net
Blazor - Introdução - Macoratti.net