DEV Community

Cover image for Blazor WebAssembly da zero!
Marco Santoni
Marco Santoni

Posted on • Updated on

Blazor WebAssembly da zero!

Blazor WebAssembly è una tecnologia sviluppata da Microsoft che sta riscuotendo discreto successo nello sviluppo di applicazioni SPA (Single Page Application).

Il nostro obiettivo

Andremo a sviluppare un'applicazione minimale basata su Blazor WebAssembly partendo dal template di un'applicazione web vuota e spiegando punto per punto il codice inserito in modo tale da comprendere come è strutturata un'applicazione Blazor WebAssembly.

Spero che questo post, oltre ad essere utile al sottoscritto per capire se veramente ha chiaro come funziona Blazor WebAssembly, possa essere d'aiuto a qualcuno che sta cominciando a muovere i primi passi con questa teconologia.

Perché?

Io non ho mai amato i template già pronti e le autocomposizioni. Specialmente quando sono all'inizio con una nuova tecnologia, ma anche dopo, preferisco sempre partire da zero (o quasi) in modo da comprendere quello che sto facendo fin dalle prime righe di codice e, successivamente, avere una migliore padronanza dell'applicazione che vado a sviluppare.

Prima di iniziare

Io sono un sostenitore delle CLI (Command Prompt, Windows Terminal, PowerShell, Bash, ecc.), in questo e nei futuri post (se ci saranno) preferirò mostrare i comandi da terminale dove possibile anziché screenshot di qualche finestra. Ciò non toglie che con gli strumenti grafici (Visual Studio e Visual Studio Code in questo caso) possiamo fare le stesse cose, quindi, a voi la scelta di come svolgere le attività qui proposte.

Cosa uso?

Se volete provare quello che scrivo in questo post, io al momento sto usando questi strumenti:

  • Windows 10
    • Command Prompt di Windows
  • .NET 5.0
  • Visual Studio 2019 (o Visual Studio Code)

L'ambiente di lavoro

La prima cosa che dobbiamo fare è creare la directory che servirà a contenere i sorgenti dell'applicazione. Io la chiamerò con pochissima fantasia BlazorWasm.

Per un'applicazione reale, dopo aver creato la directory dovrei organizzarla, ma essendo questo solo un esempio e per non perdere tempo con cose che esulano dall'argomento di questo post, il codice lo posiziono nella root della directory.

Quindi creiamo subito una directory:

mkdir BlazorWasm
cd BlazorWasm
Enter fullscreen mode Exit fullscreen mode

Io in generale, per tutti i miei progetti creo sempre una solution con un primo progetto che di solito è quello dell'interfaccia utente. Questo è il mio punto di partenza quando sviluppo.

Il prossimo passo "preparatorio" dunque è quello di creare una solution con un progetto. Mi

Creo una soluzione vuota con il comando dotnet new sln, il parametro -n permette di specificare il nome della soluzione. Se omesso, verrà creata una solution con il nome della directory (nel mio esempio il risultato con o senza il parametro sarebbe stato uguale).

dotnet new sln -n BlazorWasm
Enter fullscreen mode Exit fullscreen mode

Creo un progetto web vuoto con il comando dotnet new web, il parametro -o permette di specificare la directory che conterrà il progetto. Con il parametro -n, in maniera analoga a quanto ho fatto per la solution potrei anche specificare per il progetto un nome diverso dalla directory che lo contiene (cosa che non faccio qui).

dotnet new web -o BlazorWasmApp
Enter fullscreen mode Exit fullscreen mode

Con il comando dotnet sln BlazorWasm.sln add BlazorWasmApp.csproj aggiungo il progetto alla solution.

dotnet sln BlazorWasm.sln add BlazorWasmApp\BlazorWasmApp.csproj
Enter fullscreen mode Exit fullscreen mode

Finalmente il codice!

Bene, è arrivato il momento di aprire la solution BlazorWasm.sln con Visual Studio (2019 o Code) e di iniziare a scrivere un po' di codice.

Apriamo il file BlazorWasmApp.csproj e modifichiamolo nel seguente modo:

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    <PropertyGroup>
        <TargetFramework>net5.0</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.0" />
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.0" PrivateAssets="all" />
    </ItemGroup>
</Project>
Enter fullscreen mode Exit fullscreen mode

Cosa ho cambiato?

  • L'SDK del progetto è mutato, da Microsoft.NET.Sdk.Web a Microsoft.NET.Sdk.BlazorWebAssembly.
  • Ho aggiunto il nodo ItemGroup.
  • Nel nodo ItemGroup ho aggiunto i riferimenti necessari per Blazor WebAssembly.

Torniamo per un momento alla nostra amata CLI per eseguire il restore dei pacchetti appena aggiunti nel file .csproj. Dalla root del progetto (in questo esempio è BlazorWasm\BlazorWasmApp) digitiamo:

dotnet restore
Enter fullscreen mode Exit fullscreen mode

Nuovamente in Visual Studio, dal progetto cancello il file Startup.cs che non ci servirà e modifichiamo il file Program.cs nel seguente modo:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

namespace BlazorWasmApp
{
    public class Program
    {
        public async static Task Main(string[] args)
        {
            WebAssemblyHostBuilder builder = WebAssemblyHostBuilder.CreateDefault(args);
            // ...
            await builder.Build().RunAsync();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Arrivati a questo punto abbiamo gettato le basi per creare un'applicazione con Blazor WebAssembly. Quello che abbiamo fatto fino ad ora è creare un'applicazione che istanzia un host e lo avvia.

Proviamo ad eseguirlo con il comando dotnet run per vedere cosa succede. Il parametro --project serve a specificare quale è il progetto da avviare. Dal momento che ho eseguito il comando dalla directory BlazorWasm ho bisogno di indicare qual'è il progetto da avviare il progetto, se mi fossi posizionato nella directory BlazorWasmApp non sarebbe stato necessario il parametro.

dotnet run --project BlazorWasmApp
Enter fullscreen mode Exit fullscreen mode

Avendo eseguito dalla console l'applicazione dovremmo ottenere un risultato analogo questo:

Building...
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\Users\marco\source\BlazorWasm\
Enter fullscreen mode Exit fullscreen mode

Parte senza problemi ma quando navighiamo verso l'url indicato (https://localhost:5001 o http://localhost:5000) otteniamo un errore 404 (di pagina non trovata).

Il motivo è presto spiegato: in questo momento l'applicazione all'avvio crea e configura solamente un Host per un'applicazione Blazor WebAssembly. Per fare in modo che l'applicazione funzioni abbiamo bisogno di fare ancora un po' di lavoro. Dobbiamo ora creare:

  • Una pagina HTML statica che servirà da contenitore per i componenti che andremo a sviluppare in seugito.
  • Un componente di prova per provate il funzionamento del nostro esempio.

Creiamo due nuove directory all'interno del progetto BlazorWasmApp: una chiamata wwwroot che, come per qualsiasi altra applicazione ASP.NET Core, conterrà le risorse statiche (tra cui i file HTML) e l'altra chiamata Pages che conterrà i componenti e le pagine Razor.

mkdir wwwroot
Enter fullscreen mode Exit fullscreen mode

Dentro questa directory creo il file index.html.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Blazor WebAssembly Demo</title>
    <base href="/">
</head>
<body>
    <div id="app">Loading...</div>

    <script src="_framework/blazor.webassembly.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

La pagina non è nulla di nuovo, si tratta di una normalissima pagina HTML che ha un div con l'attributo id uguale ad app ed uno script chiamato blazor.webassembly.js.

Il div servirà sarà il punto dove Blazor andrà a caricare e visualizzare i nostri componenti, mentre il file _blazor.webassembly.js è il file di bootstrap dell'applicazione che ha il compito di scaricare il runtime di .NET (ex-Mono) sul client ed esegue l'applicazione.

Il file _blazor.webassembly.js è messo a disposizione da Blazor WebAssembly e non deve essere creato manualmente; è sufficiente incorporarlo nella pagina.

Riproviamo ora ad eseguire l'applicazione e questa volta notiamo che viene mostrata la pagina index.html in modo statico presentando solamente la stringa Loading....

Creiamo ora un primo componente, molto semplice, che ci aiuterà però a capire che la nostra applicazione sta funzionando.

Questo componente, lo chiamo HelloWorld (l'hello world è un must quando si inizia con una tecnologia 😁) e lo posiziono nella directory Pages.

@page "/helloworld"

<h1>@title</h1>

@code {
    private string title = "Hello World from Blazor WebAssembly!";
}
Enter fullscreen mode Exit fullscreen mode

Ci siamo, è arrivato il momento di specificare all'host quale sarà il componente radice che vogliamo mostrato nella pagina. Questo lo facciamo andando nel metodo Main, e dopo l'istruzione che crea il nostro Host, aggiungiamo il nostro compoenente appena creato.

public async static Task Main(string[] args)
{
    WebAssemblyHostBuilder builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.RootComponents.Add<BlazorWasmApp.Pages.HelloWorld>("#app");

    await builder.Build().RunAsync();
}
Enter fullscreen mode Exit fullscreen mode

Eseguiamo nuovamente l'applicazione e, navigando all'url, questa volta vediamo che il componente viene renderizzato.

Per concludere

Siamo giunti alla fine del post, avrei voluto trattare il routing di componenti ma scrivendo queste righe ho deciso di non farlo e di dividere in due articoli quello che inizialmente nella mia testa era uno unico.

Se volete lasciarmi qualche commento, qualche critica o suggerimento mi farebbe molto piacere.

Discussion (0)