Negli script precedenti abbiamo introdotto il nuovo concetto di Render Mode in una Blazor Web App di Blazor 8 e abbiamo visto come in questo tipo di applicazione possiamo combinare i tre tipi di rendering (Static, InteractiveServer e InteractiveWebAssembly) tutto sommato in maniera abbastanza trasparente.
Tuttavia, questo sistema di rendering flessibile, ha un importante impatto anche a livello di routing.
Prendiamo come esempio l'applicazione di default, che possiamo generare via template, con le impostazioni seguenti:
dotnet new blazor -n SampleInteractive -int WebAssembly
Come abbiamo visto nello scorso script, questo template genera due progetti, uno server e uno client, con quest'ultimo contenente la pagina Counter in modalità WebAssembly:
@page "/counter" @rendermode InteractiveWebAssembly <PageTitle>Counter</PageTitle> <h1>Counter</h1> <p role="status">Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { .. }
Intuitivamente, ci aspetteremmo che questo componente funzioni esclusivamente client side, ossia solo sul browser. Tuttavia non è questo il caso, e per dimostrarlo possiamo inserire un messaggio di log su OnInitialized:
protected override void OnInitialized() { base.OnInitialized(); Console.WriteLine("Counter.OnInitialized"); }
Proviamo ora a eseguire l'applicazione, e con nostra sorpresa noteremo che il messaggio "Counter.OnInitialized" appare due volte: una, come ci aspetteremmo, sulla finestra di log del browser, ma è anche visibile nella Console Application del server:
Questo accade perché si verificano due condizioni:
- Il componente counter ha il PreRendering attivo per default
- L'applicazione sta utilizzando il routing statico
La condizione di routing statico, in particolare, è definita dall'elemento Routes nella pagina App.razor:
<body> <Routes /> <script src="_framework/blazor.web.js"></script> </body>
Siccome non abbiamo specificato alcun RenderMode, per default il routing utilizza lo static render mode, che comporta che ogni URL, anche durante la navigazione sul sito, sia richiesto direttamente al server. Questo avviene a prescindere dal fatto che abbiamo specificato che Counter sia un componente WebAssembly, perché, come abbiamo accennato, tutti i componenti hanno il PreRendering attivo per default.
Questa logica può generare comportamenti ed errori inaspettati, quali flickering o eccezioni sulla dependency injection.
Per esempio, immaginiamo che Counter necessiti di un servizio ICounterInitializer. Dato che il componente viene eseguito due volte, una lato server e una lato client, dovremo essere sicuri di avere registrato l'implementazione di ICounterInitializer in entrambi gli IoC container, altrimenti otterremo un errore come quello in basso:
Il modo più semplice per ovviare a questo problema, è quello di disabilitare il PreRendering per il Counter, anche in virtù del fatto che questa funzionalità non è che sia così utile per il componente in questione:
@page "/counter" @rendermode @(new InteractiveWebAssemblyRenderMode(prerender:false)) <PageTitle>Counter</PageTitle> <h1>Counter</h1> <p role="status">Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
In altre situazioni, invece, soprattutto per ragioni di Search Engine Optimisation (ma non solo), potrebbe essere utile mantenere attivo il PreRendering. In questo caso ci sono delle considerazioni che dovremo fare, di cui ci occuperemo in un prossimo script.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Usare un KeyedService di default in ASP.NET Core 8
Testare l'invio dei messaggi con Event Hubs Data Explorer
Migliorare l'organizzazione delle risorse con Azure Policy
Migliorare la scalabilità delle Azure Function con il Flex Consumption
Autenticarsi in modo sicuro su Azure tramite GitHub Actions
Installare le Web App site extension tramite una pipeline di Azure DevOps
Creare una libreria CSS universale: i bottoni
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
Triggerare una pipeline su un altro repository di Azure DevOps
Paginare i risultati con QuickGrid in Blazor
Minimal API in ASP.NET Core 8
Sviluppare un'interfaccia utente in React con Tailwind CSS e Preline UI