Come creare app Web client C# con Blazor Web Framework di Microsoft

0
370

Blazor è un nuovo framework web che ti consente di creare app web completamente interattive usando C#. Utilizzando la magia di un runtime .NET compilato per WebAssembly, puoi persino eseguire Blazor interamente sul client—non devi più utilizzare framework JavaScript per creare le tue applicazioni.

Sommario

Cos'è Blazor?
Modalità ibrida
Impostare Blazer
Un tour dell'ambiente Blazor
Risolvere le orribili scelte cromatiche di Microsoft
Offrire contenuti dinamici
Come funziona lo styling?
Ciclo di vita del componente Blazer
Come funziona Blazor con JavaScript?< br/>Navigazione dell'utente nelle
biblioteche Blazer
Il futuro di Blazor

Cos'è Blazor?

Blazor è l'ultima funzionalità di ASP.NET Core, il framework Web di Microsoft di 20 anni fa. Nonostante sia vecchio, Microsoft lo mantiene ancora e ASP.NET è stato costantemente migliorato insieme a C# e al runtime .NET nel suo insieme.

Pagine Razor e il vecchio modello MVC di ASP.NET , entrambi consentono di generare pagine HTML basate sui dati utilizzando C#. È in circolazione da sempre, ma ciò che è sempre mancato è l'interattività. È piuttosto difficile creare un'app Web quando devi ricaricare la pagina per visualizzare le modifiche.

Quindi, Blazor risolve il problema collegando direttamente il server e il client con una libreria in grado di modificare il DOM in fase di esecuzione e introduce molti dei metodi del ciclo di vita dei componenti e dei gestori di aggiornamento che ti aspetteresti da un framework destinato a competere con React.

E, con la sintassi minimalista della pagina Razor, rende la codifica in Blazor un gioco da ragazzi:

Pubblicità

Blazor ha due modalità principali di funzionamento, la più interessante di cui Cliente Blazer, che impacchetta .NET stesso in un framework che può essere eseguito interamente su WebAssembly. WASM è fondamentalmente MSIL per il web; è un formato di istruzione binario leggero che qualsiasi lingua può compilare, anche “desktop” linguaggi come C++ e Rust.

Allora, come sono le prestazioni con questo? Bene, attualmente sta usando un interprete, poiché la compilazione AOT nativa per .NET è ancora in fase di elaborazione. Ma questo migliorerà alla fine; lo svantaggio principale di Blazor Client sono i tempi di download più lunghi—Le DLL possono essere file di grandi dimensioni per gli standard Web e devono essere caricate tutte per far funzionare l'applicazione. Tuttavia, anche i framework JS di grandi dimensioni presentano questo problema ed è una delle ragioni principali per cui il rendering lato server è popolare.

Compensa il tempo di download essendo molto veloce nell'aggiornamento delle pagine e nella navigazione nell'app, considerando che non deve attendere che il server lo faccia.

< /p>

Se desideri utilizzare un modello di hosting più tradizionale simile a React's Server Side Rendering (SSR), questa opzione è disponibile anche per te. È più performante e offre il vantaggio di eseguire il codice su un server affidabile.

Per raggiungere questo obiettivo, Blazor Serverpuò connettersi al client utilizzando una connessione SignalR, che è solo un wrapper di fantasia su WebSocket che può anche ricorrere a HTTP se necessario. Questo mette più stress sul server ASP.NET rispetto al web hosting tradizionale, poiché ha bisogno di ri-renderizzare e inviare nuovamente ogni singola modifica HTML a tutti i client connessi. Se hai migliaia di persone connesse, questo può essere un problema durante la scalabilità.

< /p>

Mentre Blazor è attualmente un framework Web, Microsoft sta anche realizzando Blazor Desktop, che funziona in modo molto simile a Electron impacchettando le interfacce utente Web in applicazioni desktop, così come Blazor Native, che sarà in grado di eseguire il rendering di interfacce utente native su sistemi operativi mobili. Microsoft sembra considerarlo il suo prossimo modello di programmazione delle applicazioni per creare frontend interattivi su qualsiasi piattaforma.

Modalità ibrida

Blazor può essere utilizzato anche in “modalità ibrida” utilizzando il prerendering. Blazor WASM può visualizzare HTML non elaborato durante il caricamento del framework, solitamente utilizzato per una barra di caricamento o una rotella di selezione. Tuttavia, se ospiti l'app da ASP.NET, puoi eseguire il rendering delle pagine Razor dal server prima ancora di inviare l'app al client.

Annuncio

Funziona perfettamente, con il problema che la pagina non diventerà interattiva fino a quando Blazor non verrà effettivamente caricato. Di solito ci vuole solo un secondo, quindi questo non è davvero un problema, a parte alcune stranezze nel ricaricare i dati due volte.

Con questa configurazione, ottieni il meglio di entrambi i mondi— la tua app si carica rapidamente, senza schermata di caricamento, ed è velocissima da navigare. Questa funzione è ancora in fase di elaborazione e presenta molte stranezze, ma a partire dall'anteprima 6 di .NET 6 funziona e puoi leggere di più nelle guide di Jon Hilton, parti uno e due.

Una delle stranezze è che le app WASM che si basano su un'API dovranno avere due implementazioni di ciascun servizio, sul client e sul server, in modo che il server possa parlare con se stesso per recuperare le informazioni quando esegue il pre-rendering. Ciò si traduce in alcuni lampeggi quando WASM si carica e recupera i propri dati, ma questo può essere risolto in .NET 6—questa guida mostra come mantenere lo stato del componente in modo che la tua app passi senza problemi dal falso caricamento “ pagina” all'applicazione reale.

Configurazione di Blazor

Fortunatamente Visual Studio fornisce generatori e non è necessario configurare tutto da soli. Apri Visual Studio e crea un nuovo progetto. Cerca “Blazer” e seleziona Blazor WebAssembly o Blazor Server.

Qui andremo con Blazor webassembly, poiché Blazor Server è più semplice e include solo il client e il server nello stesso progetto.

Annuncio

Dagli un nome e seleziona il tuo framework. Una cosa da notare è che Blazor WebAssembly tecnicamente non ha nemmeno bisogno di un server; puoi semplicemente ospitarlo come sito Web statico su NGINX o anche come bucket AWS S3. Tuttavia, se ti stai connettendo a un'API per parlare con un database, potresti anche creare quell'API in bundle con il client, poiché puoi condividere il codice tra di loro e ovviamente utilizzare lo stesso linguaggio.

< p>

La tua soluzione sarà impostata con tre progetti, un'applicazione client, un ASP.NET API del server e host web per il client e una libreria condivisa tra di loro.

Se fai clic su Avvia, vedrai ASP.NET avviarsi e servire la pagina web. Se stai usando Blazor Server, si connetterà ad ASP.NET su SignalR per gestire le interazioni.

Naturalmente, Blazor WebAssembly invierà richieste al server solo se fatte esplicitamente dall'applicazione .

Un tour dell'ambiente Blazor

Facciamo un tour dell'applicazione. A partire dal client, il punto di ingresso principale è Program.cs, che crea il WebAssemblyHost, aggiunge il componente radice App.razor, quindi compila ed esegue l'app.

Tecnicamente, il punto di ingresso è wwwroot/index.html, che carica Blazor’ s JavaScript, mostra una pagina di caricamento durante l'inizializzazione di Blazor e mostra un messaggio di errore se non lo fa.

Pubblicità

App.razor gestisce il routing delle pagine utilizzando un componente Router. Questo accetta l'assembly e carica tutte le pagine contrassegnate con l'attributo @page name. Puoi saperne di più sul routing nelle pagine Razor qui.

Il router carica il componente MainLayout.razor, che estende LayoutComponentBase. Questo carica il componente NavMenu.razor accanto al corpo e visualizza la tua applicazione.

Grande! Per quanto riguarda il server, è un'applicazione ASP.NET standard. Crea un generatore di host e aggiunge i servizi configurati in Startup.cs. In particolare, lo configura per il debug WASM, serve i file Blazor Framework e configura le proprie pagine e controller Razor per servire il contenuto JSON.

Se questa fosse solo un'app Blazor Server, non avrebbe bisogno di questa API separata e potrebbe semplicemente recuperare i dati da un servizio interno. Ma poiché non lo è, deve esporre quel servizio in rete, sotto forma di un ApiController ASP.NET che specifica i metodi del gestore per diverse azioni HTTP.

I modelli per questo sono condivisi tra client e server, nel progetto condiviso.

Risolvere le orribili scelte cromatiche di Microsoft

Prima di dedicarci al codice, dobbiamo sistemare qualcosa. Per qualche ragione, la scelta cromatica predefinita di Microsoft per le direttive HTML C# nelle pagine Razor utilizza quella che è forse la peggiore combinazione di colori immaginabile, ovvero testo viola chiaro su uno sfondo marrone chiaro.

Per fortuna tu può cambiarlo da Strumenti > Opzioni:

Pubblicità

In ambiente > Caratteri e colori, seleziona “Direttiva rasoio” e cambia il colore di sfondo in qualcosa di più ragionevole. Probabilmente vuoi ancora che si distingua, quindi ho scelto il nero puro, che sarà evidente ma non invadente.

Devi anche cambiare “Script lato server HTML,” (che tecnicamente è ormai un nome obsoleto considerando l'esistenza di Blazor WebAssembly).

E con questa semplice soluzione, puoi risparmiare ore di dolore ai tuoi occhi.

Elaborazione di contenuti dinamici

L'ultimo file che vorrai estrarre è sul client, FetchData.razor. È qui che il client utilizza effettivamente l'API lato server, con la seguente pagina basata sui dati:

Questa è una pagina Razor abbastanza complessa, quindi per noi è un buon esempio da analizzare qui.

Per iniziare, specifica un override manuale per il percorso della pagina con @page “/fetchdata”. Quindi importa i modelli condivisi dal progetto condiviso e utilizza anche l'iniezione di dipendenza per dargli un HttpClient, che è stato impostato in Program.cs.

Annuncio

Passeremo a in basso per spiegare questo primo—il blocco @code contiene il codice C# effettivo per questa pagina. In esso, c'è una variabile privata chiamata forecasts. Inizialmente è nullo, ma quando la pagina viene inizializzata, effettua una richiesta web per acquisire i dati dall'API e deserializzarli.

Quando tale variabile viene aggiornata, Blazor rileva la modifica e esegue nuovamente il rendering della pagina. La pagina stessa è tutto il resto, che inizia con un'intestazione e una descrizione, ma poi contiene un'istruzione @if. Questo è HTML condizionale C# e in questo caso viene usato per mostrare il caricamento del testo mentre Blazor sta effettuando la richiesta all'API. Quindi, una volta terminato e riprodotto, le previsioni non saranno nulle e renderà la tabella che farà l'elemento @foreach nell'elenco e renderà una riga della tabella.

Usando questo, puoi eseguire il rendering del contenuto dinamico dai tuoi modelli. Per supportare operazioni CRUD più avanzate e interfacce utente più dinamiche, sarà necessario utilizzare pulsanti e input. Puoi utilizzare il <pulsante> tag con un attributo @onclick, che accetta un riferimento al metodo.

< p>Puoi utilizzare EventCallbacks per passare l'evento ai componenti principali. Puoi anche utilizzare le espressioni Lambda per gestire gli eventi in linea, se il metodo è breve:

<button @onclick=”@(e => header = “Nuova intestazione!!!”)”> Aggiorna intestazione </button>

Esistono più argomenti di evento aggiuntivi che puoi passare a queste funzioni del gestore, inclusi la posizione del mouse, gli eventi della tastiera e gli eventi tocco.

Se vuoi implementare una casella di ricerca, Blazor ha dei binding per questo. Tuttavia, se si desidera che esegua la ricerca automaticamente quando si preme invio e non a ogni pressione dei tasti, è necessario associare l'evento @onkeydown a una funzione, che accetta un oggetto KeyboardEventArgs e controllare manualmente se è stato premuto Invio.

Pubblicità

Tuttavia, non è possibile ottenere il valore di input da KeyboardEventArgs, quindi si ottiene questa casella di input disordinata in cui è necessario associare onkeydown e oninput, impostare un valore di stringa e quindi utilizzare quella stringa in 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”) { //fai cose } } }

Come funziona lo styling?

Estremamente semplice. Esiste un file master site.css, ma per lo stile a livello di componente, basta creare un file .razor.css per ogni pagina Razor:

index.razor index.razor.css

Blazor creerà automaticamente un file CSS con ambito che applica le impostazioni di ogni pagina Razor solo a quella pagina Razor:

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

Far funzionare pre-processori come SASS è un po' più complicato, ma completamente fattibile.

Ciclo di vita del componente Blazer

Come React, Blazer dispone anche di associazioni del ciclo di vita dei componenti. Secondo questo diagramma della Blazor University, una risorsa fantastica per l'apprendimento di Blazor, il runtime di Blazor li chiama nel seguente ordine:

SetParametersAsync e OnParametersSet vengono chiamati ogni volta che viene eseguito il rendering del padre del componente. OnInitializedAsync viene chiamato anche qui se è la prima volta. Quindi, per ogni interazione dell'utente, l'evento può chiamare StateHasChanged, che verifica se deve essere visualizzato e riavvia il processo di aggiornamento.

Annuncio

Ci sono troppi dettagli da elencare qui, quindi dovresti leggere la guida della Blazor University, che li spiega tutti, così come le strane interazioni con i metodi asincroni/attendi. Per rendere più contenuto il più velocemente possibile, Blazor può eseguire StateHasChanged ed eseguire il rendering due volte, una volta quando viene restituito l'oggetto Task waiter e una volta al termine.

Come funziona Blazor con JavaScript?

Indipendentemente dal fatto che utilizzi Blazor Server o Blazor Desktop, hai l'interoperabilità completa di JavaScript, come la chiamata di funzioni JS dal codice gestito:

attività asincrona privata ConvertArray() { text = new(attendere JS.InvokeAsync<string>(“convertArray”, quoteArray)); }

E chiamando .NET da JS:

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

Puoi effettivamente utilizzare tutti i pacchetti NPM con Blazor, anche se dovresti preferire un pacchetto NuGet per la maggior parte del tempo se è un'opzione.

Navigazione dell'utente intorno

Uno dei problemi più importanti con le app Web, in particolare le app Web a pagina singola (SPWA), è il routing. Ogni pagina Razor ha un percorso predefinito in base al suo nome, ma puoi sovrascriverlo e puoi anche aggiungere più percorsi di pagina a ogni pagina Razor. Il router abbinerà ciascuno separatamente e servirà ancora lo stesso file.

Tuttavia, se desideri offrire contenuti diversi a seconda dell'URL in cui ti trovi, le cose si complicano un po'. La soluzione più semplice sarebbe definire una route @page per ogni stringa che si desidera aggiungere. Funziona la prima volta, ma a causa del modo in cui Blazor gestisce gli aggiornamenti, non aggiornerà la pagina quando si accede a un nuovo URL perché i parametri non sono cambiati. Puoi ancora usarlo per definire più ortografie della stessa pagina, a patto che quelle pagine non siano collegate tra loro.

La soluzione al problema SPWA è usare route basate su parametri ogni volta che vogliono catturare più opzioni e collegare tra loro. I parametri possono essere definiti tra parentesi:

Pubblicità

Questa particolare configurazione è per la pagina principale. Se sei preoccupato che corrisponda ad altre pagine come /error poiché è configurato per corrispondere a qualsiasi cosa dopo root, non preoccuparti, Blazor abbinerà altre pagine che sono rigorosamente definite prima di ricorrere all'utilizzo di route basate su parametri. Tuttavia, non puoi avere più route di parametri sulla stessa route root senza ricevere un errore di route ambiguo.

Nel mio caso, volevo indirizzare l'utente a una nuova pagina con un argomento. Puoi farlo accedendo al NavigationManager e chiamando NavigateTo:

NavManager.NavigateTo(“/search/” + searchValue);

Se desideri un routing più avanzato, dovrai esaminare i parametri di query.

Aggiornamento manuale della pagina al cambio dell'URL

Una delle peculiarità di Blazor è che non attiva un aggiornamento quando l'URL cambia, anche se disponi di codice stateful che dipende da esso, quindi dovrai aggiornare manualmente. Fortunatamente, il NavigationManager ha un delegato per quando la posizione cambia e puoi associare una funzione a quella.

NavigationManager.LocationChanged += HandleLocationChanged;

Ti consigliamo di utilizzare InvokeAsync con una funzione che aggiorna qualsiasi oggetto di stato da cui dipende la tua app. Quindi, dovrai chiamare StateHasChanged in seguito per attivare un aggiornamento.

< /p>

Puoi anche chiamare OnParametersSetAsync da qui, se il tuo codice dipende anche da altri parametri URL e non vuoi copiare/incollare.

Blazor Librerie

Uno dei vantaggi di Blazor è che non è una cosa nuova di zecca, è costruito sulla dorsale ventennale di ASP.NET e quindi è già dotato di un ecosistema diversificato di librerie. Non entreremo in un elenco di questi qui, perché c'è già un fantastico elenco di blazer su GitHub che copre tutto.

Pubblicità

Tuttavia, una cosa che dovresti assolutamente fare utilizzare è una libreria di componenti prefabbricata. Ce ne sono un paio gratuiti, ma RadZen è uno dei più popolari ed è completamente open source. Blazorise è un altro fantastico, anche se è gratuito solo per i prodotti non commerciali.

In entrambi i casi, l'utilizzo di layout di componenti prefabbricati e la loro modellazione manuale in un secondo momento consentirà una rapida prototipazione e accelererà drasticamente i tempi di sviluppo. Li consigliamo vivamente.

Il futuro di Blazor

Blazor è un framework davvero unico in un oceano di cloni di React basati su JavaScript e, con Microsoft alle spalle, ha un futuro brillante. Abbiamo detto in precedenza che Microsoft aveva in programma Blazor Desktop, che arriverà alla fine del 2021.

Blazor Desktop funzionerà in modo molto simile a Electron, dove avvierà la tua app in un contenitore Chromium con alcuni collegamenti per la funzionalità desktop . Tranne che, invece di utilizzare Chromium, Blazor Desktop utilizzerà WebView nativi ed eseguirà il codice .NET direttamente sulla macchina.

Nel frattempo, puoi effettivamente ottenere Blazor sul desktop ora con Electron .NET e funziona sorprendentemente bene. Tutto quello che devi fare è installarlo e aggiungere Electron come servizio ASP.NET. Puoi anche chiamare le funzioni native di Electron da C#.