Cursos

[Noticias][grids]

Como criar aplicativos da Web cliente em C # com o Blazor Web Framework da Microsoft

 

Blazor é uma nova estrutura da web que permite criar aplicativos da web totalmente interativos usando C #. Usando a magia de um runtime . NET compilado para WebAssembly, você pode até mesmo executar o Blazor inteiramente no cliente — você não precisa mais usar frameworks JavaScript para criar seus aplicativos.

ÍndiceO que é o Blazor? Modo híbridoConfigurando o BlazorUm tour pelo ambiente do BlazorFixando as escolhas de cores terríveis da Microsoft Servindo conteúdo dinâmicoComo funciona o estilo? Ciclo de vida do componente BlazorComo o Blazor funciona com JavaScript? Navegando para o usuário AroundBlazor LibrariesThe Future Of Blazor

O que é Blazor?

Blazor é o recurso mais recente do ASP. NET Core, a estrutura da web da Microsoft com 20 anos de idade. Apesar de ser antigo, a Microsoft ainda o mantém, e o ASP. NET tem melhorado consistentemente junto com o C # e o tempo de execução do . NET como um todo.

As páginas do Razor e o antigo modelo MVC da ASP. NET permitem que você gere páginas HTML controladas por dados usando C #. Isso existe desde sempre, mas o que sempre faltou foi a interatividade. É muito difícil fazer um aplicativo da web quando você precisa recarregar a página para visualizar as alterações.

Então, o Blazor resolve isso vinculando diretamente o servidor e o cliente a uma biblioteca que pode modificar o DOM em tempo de execução e traz muitos dos métodos de ciclo de vida do componente e manipuladores de atualização que você esperaria de uma estrutura pretendida para competir com o React.

E, com a sintaxe minimalista da página do Razor, torna a codificação no Blazor uma brisa:

Publicidade

O Blazor tem dois modos principais de operação, o mais legal deles é o Blazor Client, que empacota o próprio . NET em uma estrutura que pode ser executada inteiramente no WebAssembly. WASM é basicamente MSIL para a web; é um formato de instrução binário leve que qualquer linguagem pode compilar, até mesmo “ desktop ” linguagens como C ++ e Rust.

Então, como está o desempenho com isso? Bem, atualmente ele está usando um intérprete, pois a compilação AOT nativa para . NET ainda está sendo trabalhada. Mas isso vai melhorar eventualmente; a principal desvantagem do Blazor Client são os tempos de download mais longos — DLLs podem ser arquivos grandes para os padrões da web e todos eles precisam ser carregados para que o aplicativo esteja instalado e funcionando. No entanto, grandes estruturas JS também têm esse problema e é um grande motivo pelo qual a renderização do lado do servidor é popular.

Ele compensa o tempo de download sendo muito rápido para atualizar as páginas e navegar pelo aplicativo, considerando que não é necessário esperar que o servidor o faça.

Se você deseja usar um modelo de hospedagem mais tradicional semelhante ao React &’ s Server Side Rendering (SSR), essa opção também está disponível para você. É mais eficiente e vem com a vantagem de executar o código em um servidor confiável.

Para conseguir isso, o Blazor Server pode se conectar ao cliente usando uma conexão SignalR, que é apenas um invólucro sofisticado sobre WebSockets que também pode retornar para HTTP se necessário. Isso coloca mais estresse no servidor ASP. NET do que a hospedagem tradicional na Web, pois ele precisa renderizar novamente e reenviar todas as alterações de HTML para todos os clientes conectados. Se você tiver milhares de pessoas conectadas, isso pode ser um problema durante a expansão.

Embora o Blazor seja atualmente uma estrutura da web, a Microsoft também está fazendo o Blazor Desktop, que funciona muito como o Electron, empacotando UIs da web em aplicativos de desktop, bem como Blazor Native, que será capaz de renderizar interfaces de usuário nativas em sistemas operacionais móveis. A Microsoft parece pensar nisso como seu próximo modelo de programação de aplicativo para fazer front-ends interativos em qualquer plataforma.

Modo híbrido

O Blazor também pode ser usado em um “ modo híbrido ” usando pré-renderização. O Blazor WASM pode exibir HTML bruto enquanto a estrutura é carregada, geralmente usado para uma barra de carregamento ou roda giratória. Mas, se você hospedar o aplicativo do ASP. NET, poderá renderizar as páginas do Razor do servidor antes mesmo de enviar o aplicativo para o cliente.

Publicidade

Isso funciona perfeitamente, com a captura de que a página não se tornará interativa até que o Blazor realmente carregue. No entanto, geralmente leva apenas um segundo, então isso não é realmente um problema, além de algumas peculiaridades em recarregar os dados duas vezes.

Com esta configuração, você obtém o melhor dos dois mundos — seu aplicativo carrega rapidamente, sem tela de carregamento, e é extremamente rápido navegar. Esse recurso ainda está sendo trabalhado e vem com muitas peculiaridades, mas a partir da visualização 6 do . NET 6, ele está funcionando e você pode ler mais nos guias de Jon Hilton, partes um e dois.

Uma das peculiaridades é que os aplicativos WASM que dependem de uma API terão que ter duas implementações de cada serviço, no cliente e no servidor, para que o servidor possa se comunicar com buscar as informações quando for pré-renderizado. Isso resulta em alguns flashes quando o WASM carrega e faz sua própria busca de dados, mas isso pode ser corrigido no . NET 6 — este guia mostra como manter o estado do componente para que seu aplicativo faça uma transição perfeita do carregamento falso página ” para a aplicação real.

Configurando o Blazor

Felizmente, o Visual Studio fornece geradores e você não precisa configurar tudo sozinho. Abra o Visual Studio e crie um novo projeto. Pesquise por “ Blazor ” e selecione Blazor WebAssembly ou Blazor Server.

Vamos usar o Blazor WebAssembly aqui, pois o Blazor Server é mais simples e inclui apenas o cliente e o servidor no mesmo projeto.

Publicidade

Dê a ele um nome e selecione sua estrutura. Uma coisa a observar é que o Blazor WebAssembly tecnicamente nem mesmo precisa de um servidor; você pode apenas hospedá-lo como um site estático no NGINX ou até mesmo um bucket AWS S3. Mas, se você estiver se conectando a uma API para se comunicar com um banco de dados, você também pode fazer essa API empacotada com o cliente, já que você pode compartilhar o código entre eles e, claro, usar a mesma linguagem.

Sua solução será configurada com três projetos, um aplicativo cliente, uma API de servidor ASP. NET e host da web para o cliente e uma biblioteca compartilhada entre eles.

Se você clicar em iniciar, verá o ASP. NET inicializar e exibir a página da web. Se você estiver usando o Blazor Server, ele se conectará ao ASP. NET pelo SignalR para lidar com as interações.

Obviamente, o Blazor WebAssembly só enviará solicitações ao servidor quando feitas explicitamente pelo aplicativo.

Um tour pelo ambiente Blazor

Vamos fazer um tour pelo aplicativo. Começando com o cliente, o ponto de entrada principal é Program. cs, que cria o WebAssemblyHost, adiciona o componente App. razor raiz e, em seguida, cria e executa o aplicativo.

Tecnicamente, o ponto de entrada é wwwroot / index. html, que carrega o arquivo JavaScript do Blazor, mostra uma página de carregamento enquanto o Blazor é inicializado e mostra uma mensagem de erro se não o fizer.

Publicidade

App. razor lida com o roteamento de páginas usando um componente Roteador. Isso leva na montagem e carrega todas as páginas marcadas com o atributo @page name. Você pode aprender mais sobre roteamento nas páginas do Razor aqui.

O roteador carrega o componente MainLayout. razor, que estende LayoutComponentBase. Isso carrega o componente NavMenu. razor ao lado do corpo e exibe seu aplicativo.

Ótimo! Quanto ao servidor, é um aplicativo ASP. NET padrão. Ele cria um construtor de host e adiciona serviços configurados em Startup. cs. Notavelmente, ele o configura para depuração WASM, serve os arquivos do Blazor Framework e configura suas próprias páginas e controladores do Razor para servir conteúdo JSON.

Se este fosse apenas um aplicativo Blazor Server, não precisaria dessa API separada e poderia apenas buscar dados de um serviço interno. Mas, como não é, ele precisa expor esse serviço durante a transmissão, na forma de um ApiController ASP. NET que especifica métodos de manipulação para diferentes ações HTTP.

Os modelos para isso são compartilhados entre cliente e servidor, no projeto compartilhado.

Consertando as opções de cores terríveis da Microsoft

Antes de começar a codificar, precisamos consertar algo. Por alguma razão, a escolha de cor padrão da Microsoft para as diretivas HTML C # nas páginas do Razor é usar o que é talvez a pior combinação de cores imaginável — texto roxo claro em um fundo castanho claro.

Felizmente, você pode alterá-lo em Ferramentas > Opções:

Publicidade

Em Ambiente > Fontes e cores, selecione “ Diretriz do Razor ” e mude a cor de fundo para algo mais razoável. Você provavelmente ainda quer que ele se destaque, então escolhi o preto puro, que será perceptível, mas não intrusivo.

Você também precisará alterar o “ HTML Server-Side Script, ” (que tecnicamente agora é um nome desatualizado, considerando a existência do Blazor WebAssembly).

E com essa solução simples, você pode economizar horas de dor para seus olhos.

Veiculação de conteúdo dinâmico

O último arquivo que você deseja verificar está no cliente, FetchData. razor. É aqui que o cliente realmente consome a API do lado do servidor, com a seguinte página controlada por dados:

Esta é uma página do Razor bastante complexa, portanto, é um bom exemplo para analisarmos aqui.

Para começar, ele especifica uma substituição manual para a rota da página com @page "/ fetchdata". Em seguida, importa os modelos compartilhados do projeto compartilhado e também usa injeção de dependência para fornecer um HttpClient, que foi configurado em Program. cs.

Publicidade

Pularemos para o final para explicar isso primeiro — o bloco @code contém o código C # real para esta página. Nele, há uma variável privada chamada previsões. Isso é inicialmente nulo, mas quando a página é inicializada, ela faz uma solicitação da web para obter os dados da API e desserializá-los.

Quando essa variável é atualizada, o Blazor detecta a mudança e renderiza novamente a página. A página em si é tudo no meio, que começa com um cabeçalho e uma descrição, mas contém uma instrução @if. Este é o HTML condicional C # e, neste caso, é usado para mostrar o texto de carregamento enquanto o Blazor está fazendo a solicitação à API. Então, depois de terminar e renderizar novamente, as previsões não serão nulas e renderizará a tabela que fará @foreach elemento na lista e renderizará uma linha da tabela.

Usando isso, você pode renderizar conteúdo dinâmico de seus modelos. Para suportar operações CRUD mais avançadas e interfaces de usuário mais dinâmicas, você precisará usar botões e entradas. Você pode usar o < button > tags com um atributo @onclick, que leva uma referência de método.

Você pode usar EventCallbacks para passar o evento aos componentes pais. Você também pode usar expressões Lambda para lidar com eventos embutidos, se o método for curto:

 < botão @onclick = "@ (e = > header =" Novo título !!! ")" > Atualizar título < / botão > 

Existem vários argumentos de evento adicionais que você pode passar para essas funções de manipulador, incluindo localização do mouse, eventos de teclado e eventos de toque.

Se você deseja implementar uma caixa de pesquisa, o Blazor possui vínculos para isso. No entanto, se você quiser que ele pesquise automaticamente ao pressionar Enter, e não a cada pressionamento de tecla, você precisará vincular o evento @onkeydown a uma função, que usa um objeto KeyboardEventArgs, e verificar manualmente se Enter foi pressionado.

Publicidade

No entanto, você não pode obter o valor de entrada do KeyboardEventArgs, então isso resulta nesta caixa de entrada confusa onde você deve vincular onkeydown e oninput, definir um valor de string e, em seguida, usar essa string em onkeydown.

 < input type = "text" @onkeydown = "@ Enter" @oninput = "@ (ui = > {searchValue = (string) ui. Value;})" / > @code {public void Enter (KeyboardEventArgs e) {if (e. Code == "Enter" || e. Code == "NumpadEnter") {// do stuff}}} 

Como funciona a estilização?

Extremamente simples. Há um arquivo mestre site. css, mas para estilo de nível de componente, basta criar um arquivo . razor. css para cada página do Razor:

 index. razor index. razor. css 

O Blazor criará automaticamente um arquivo CSS com escopo definido que aplica as configurações de cada página do Razor somente a essa página do Razor:

 < link href = "BlazorWebAssemblyTest. Client. styles. css" rel = "stylesheet" / > / * /Pages/Counter. razor. rz. scp. css * / h1 [b-3xxtam6d07] {color: brown; }

Fazer com que pré-processadores como o SASS funcionem é um pouco mais complicado, mas totalmente factível.

Ciclo de vida do componente Blazor

Assim como o React, o Blazor também possui vínculos de ciclo de vida de componentes. De acordo com este diagrama da Blazor University, um recurso fantástico para aprender o Blazor, o tempo de execução do Blazor os chama na seguinte ordem:

SetParametersAsync e OnParametersSet são chamados sempre que o pai do componente é renderizado. OnInitializedAsync também é chamado aqui se for a primeira vez. Então, para cada interação do usuário, o evento pode chamar StateHasChanged, que verifica se ele deve ser renderizado e dispara esse processo de atualização novamente.

Publicidade

Existem muitos detalhes para listar aqui, então você deve ler o guia da Blazor University, que explica todos eles, bem como interações estranhas com métodos assíncronos / espera. Para renderizar o máximo de conteúdo o mais rápido possível, o Blazor pode executar StateHasChanged e renderizar duas vezes, uma vez quando o objeto Task awaiter é retornado e uma vez quando é concluído.

Como o Blazor funciona com JavaScript?

Independentemente de usar o Blazor Server ou o Blazor Desktop, você tem interoperabilidade total de JavaScript, como chamar funções JS a partir do código gerenciado:

 private assíncrono Tarefa ConvertArray () {text = new (await JS. InvokeAsync < string > ("convertArray", quoteArray)); }

E chamando . NET de JS:

 DotNet. invokeMethodAsync ('', '{. NET METHOD ID}',); 

Na verdade, você pode usar todos os pacotes NPM com o Blazor, embora deva preferir um pacote NuGet na maioria das vezes, se for uma opção.

Navegando pelo usuário

Um dos problemas mais importantes com os aplicativos da web, especialmente os aplicativos da web de página única (SPWAs), é o roteamento. Cada página do Razor tem uma rota padrão de acordo com seu nome, mas você pode sobrescrever isso, e você também pode adicionar várias rotas de página a cada página do Razor. O roteador corresponderá a cada um separadamente e ainda servirá o mesmo arquivo.

No entanto, se você deseja veicular conteúdo diferente dependendo de qual URL você está usando, as coisas ficam um pouco complicadas. A solução mais simples seria apenas definir uma rota @page para cada string que você deseja adicionar. Isso funciona na primeira vez, mas devido à maneira como o Blazor lida com as atualizações, não atualizará a página ao navegar para um novo URL porque os parâmetros não mudaram. Você ainda pode usar isso para definir várias grafias da mesma página, desde que essas páginas não tenham links entre si.

A solução para o problema do SPWA é usar rotas baseadas em parâmetros sempre que você quiser capturar várias opções e vincular entre elas. Os parâmetros podem ser definidos entre colchetes:

Publicidade

Esta configuração específica é para a página raiz. Se você estiver preocupado com a possibilidade de corresponder a outras páginas como / error, já que está configurado para corresponder a qualquer coisa após o root, não se preocupe, o Blazor irá corresponder a outras páginas estritamente definidas antes de voltar a usar rotas baseadas em parâmetros. No entanto, você não pode ter várias rotas de parâmetro na mesma rota raiz sem obter um erro de rota ambíguo.

No meu caso, eu queria navegar o usuário para uma nova página com um argumento. Você pode fazer isso acessando o NavigationManager e chamando NavigateTo:

 NavManager. NavigateTo ("/ search /" + searchValue); 

Se desejar um roteamento mais avançado, você &’ precisará examinar os Parâmetros de consulta.

Atualização manual da página na alteração do URL

Uma das peculiaridades do Blazor é que ele não aciona uma atualização quando o seu URL muda, mesmo se você tiver um código com estado que dependa dele, então você precisará atualizar manualmente. Felizmente, o NavigationManager tem um delegado para quando o local muda e você pode vincular uma função a ele.

 NavigationManager. LocationChanged + = HandleLocationChanged; 

Você deseja usar InvokeAsync com uma função que atualiza qualquer objeto de estado do qual seu aplicativo depende. Em seguida, você precisará chamar StateHasChanged depois para acionar uma atualização.

Você também pode chamar OnParametersSetAsync a partir daqui, se o seu código também depender de outros parâmetros de URL e você não quiser copiar / colar.

Bibliotecas Blazor

Um dos benefícios do Blazor é que ele não é uma coisa totalmente nova, ele foi desenvolvido na espinha dorsal de 20 anos do ASP. NET e, portanto, já vem com um ecossistema diversificado de bibliotecas. Não entraremos em uma lista deles aqui, porque já existe uma lista incrível no GitHub que cobre tudo.

Publicidade

No entanto, algo que você definitivamente deve usar é uma biblioteca de componentes pré-fabricada. Existem alguns gratuitos, mas RadZen é um dos mais populares e é totalmente de código aberto. Blazorise é outro ótimo, embora seja gratuito apenas para produtos não comerciais.

Em ambos os casos, usar layouts de componentes pré-fabricados e estilizá-los manualmente mais tarde permitirá uma prototipagem rápida e acelera drasticamente o tempo de desenvolvimento. Nós os recomendamos altamente.

O futuro do Blazor

O Blazor é uma estrutura verdadeiramente única entre um oceano de clones React baseados em JavaScript e, com a Microsoft por trás disso, tem um futuro brilhante. Mencionamos anteriormente que a Microsoft tinha planos para o Blazor Desktop, que será lançado no final de 2021.

O Blazor Desktop funcionará muito como o Electron, onde inicia seu aplicativo em um contêiner do Chromium com algumas ligações para a funcionalidade do desktop. Exceto que, em vez de usar o Chromium, o Blazor Desktop usará WebViews nativos e executará o código . NET diretamente na máquina.

Enquanto isso, você pode realmente ter o Blazor na área de trabalho agora com Electron. NET, e ele funciona surpreendentemente bem. Tudo que você precisa fazer é instalá-lo e adicionar Electron como um serviço ASP. NET. Você também pode chamar funções nativas do Electron em C #.