Nella creazione di un progetto Blazor Server viene utilizzato il template di default, vediamo insieme come è organizzata la struttura di base e quali sono i files principali.

In questo articolo:

Organizzazione del progetto

Il file di progetto [.csproj]

Il punto d’ingresso [Progam.cs]

Il file di avvio [Startup.cs]

Il file di configurazione [appsettings.json]

Il file di rendering [App.razor]

Il file di direttiva [_Imports.razor]

La cartella WWWROOT

La cartella Data

La cartella Pages

La cartella Shared

Conclusioni

Organizzazione del progetto

Dopo selezionato l’opzione Blazor Server in Visual Studio, verrà aperto il template di default ed il nostro progetto avrà la seguente struttura:

Questa (ad eccezione della cartella “Database” creata da me) è la tipica struttura di un progetto Blazor Server.

Il file di progetto [.csproj]

Le applicazioni Blazor Server sono progetti .NET Core e nel file “.csproj” sono contenute le informazioni relative al “TargetFramework”, le librerie di riferimento “PackageReference” e gli eventuali riferimenti ad altri progetti “ProjectReference” presenti nella soluzione.

<Project Sdk="Microsoft.NET.Sdk.Web">

 <PropertyGroup>
   <TargetFramework>netcoreapp3.1</TargetFramework>
 </PropertyGroup>

 <ItemGroup>
   <PackageReference Include="..." Version="..." />
 </ItemGroup>

 <ItemGroup>
   <ProjectReference Include="..." />
 </ItemGroup>
   
</Project>

I progetti Blazor WebAssembly hanno come destinazione .NET Standard anziché .NET Core perché vengono eseguiti nel browser a runtime. Non essendo possibile installare tutto il framework .NET nel browser, nel file di progetto troveremo i riferimenti ai singoli pacchetti utilizzati.

Il punto d’ingresso [Program.cs]

Il punto di ingresso delle applicazioni Blazor Server viene definito nel file “Program.cs“. All’avvio dell’applicazione, viene creata ed eseguita un’istanza dell’Host usando le impostazioni predefinite per le web app. L’Host Web gestisce il ciclo di vita dell’applicazione e ne istanzia i servizi. Questo codice è per lo più standard e viene spesso lasciato invariato.

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace BlazingCode.Server
{
   public class Program
  {
       public static void Main(string[] args)
      {
           CreateHostBuilder(args).Build().Run();
      }

       public static IHostBuilder CreateHostBuilder(string[] args) =>
           Host.CreateDefaultBuilder(args)
              .ConfigureWebHostDefaults(webBuilder =>
              {
                   webBuilder.UseStartup<Startup>();
              });
  }

}

Anche le applicazioni Blazor WebAssembly hanno come punto d’ingresso il file “Program.cs” ma il codice è leggermente differente. Tramite il metodo CreateDefaultBuilder vengono istanziati gli stessi servizi ad eccezione di quello HTTP dato che l’applicazione gira direttamente nel browser.

Il file di avvio [Startup.cs]

La classe “Startup.cs” contiene la logica di avvio dell’applicazione e viene usata per configurare i servizi. Nel metodo “ConfigureServices” viene aggiunto il supporto alle pagine Razor e ai componenti Blazor. Nel metodo “Configure” vengono impostati gli endpoints di Blazor: l’Hub SignalR e l’indirizzo verso il quale navigare in caso di pagina non trovata.

namespace BlazingCode.Server
{
   public class Startup
  {
       public Startup(IConfiguration configuration)
      {
           Configuration = configuration;
      }

       public IConfiguration Configuration { get; }
   
       public void ConfigureServices(IServiceCollection services)
      {
           
           // configura il supporto alle pagine Razor e ai camponenti Blazor
           services.AddRazorPages();
           services.AddServerSideBlazor();
   
           // registra la stringa di connessione al db
           services.AddEntityFrameworkSqlite().AddDbContext<SqlDbContext>();
   
           // registra la classe ClienteService
           services.AddScoped<IClienteService, ClienteService>();
   
      }
   
       public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
      {
           if (env.IsDevelopment())
          {
               app.UseDeveloperExceptionPage();
          }
           else
          {
               app.UseExceptionHandler("/Error");
               app.UseHsts();
          }
   
           app.UseHttpsRedirection();
           app.UseStaticFiles();
   
           app.UseRouting();
   
           app.UseEndpoints(endpoints =>
          {
               endpoints.MapBlazorHub();
               endpoints.MapFallbackToPage("/_Host");
          });
      }
  }

}

Il file di configurazione [appsettings.json]

Il file “appsetting.json” può essere utilizzato per archiviare alcuni parametri come vedremo più avanti nello sviluppo della nostra applicazione.

ATTENZIONE: non archiviare mai le password o altri dati sensibili nel file di configurazione.

{
 "Logging": {
   "LogLevel": {
     "Default": "Information",
     "Microsoft": "Warning",
     "Microsoft.Hosting.Lifetime": "Information"
  }
},
 "AllowedHosts": "*"
}

Al momento, le applicazioni Blazor WebAssembly non supportano il file “appsetting.json”.

Il file di rendering [App.razor]

Il file “App.razor” è il componente radice dell’applicazione e si compone a sua volta di altri componenti Razor tra i quali Router, Found, NotFound, LayoutView;

<Router AppAssembly="@typeof(Program).Assembly">
   <Found Context="routeData">
       <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
   </Found>
   <NotFound>
       <LayoutView Layout="@typeof(MainLayout)">
           <p>Sorry, there's nothing at this address.</p>
       </LayoutView>
   </NotFound>
</Router>

Razor è un linguaggio di markup basato su HTML e C#. La logica di rendering di un componente viene creata usando il normale markup HTML unita al codice C# usando il carattere @.

Il file di direttiva [_Imports.razor]

Il file “_Imports.razor” non è un componente Razor. Definisce, invece, un set di direttive da importare. E’ un modo convenzionale per aggiungere le istruzioni “using” di uso comune per la nostra applicazione.

@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.JSInterop
@using BlazingCode.Server
@using BlazingCode.Server.Shared

La cartella WWWROOT

Solo i file nella cartella “wwwroot” possono essere richiamati dal browser. Questa cartella viene definita “radice Web” e qualsiasi elemento al suo esterno non è indirizzabile sul Web. Questa configurazione offre un livello di sicurezza che impedisce l’esposizione accidentale dei file di progetto sul Web. In questa cartella andremo a collocare i file statici quali: css, immagini, javascript, file ico, ecc.

La cartella Data

Nella cartella “Data” andremo a collocare le classi che definiscono la struttura dei dati, le loro interfacce ed il DbContext.

La cartella Pages

Blazor non definisce un’estensione di file separata per le pagine web. Le pagine vengono definite tramite il routing ai componenti che viene assegnato usando la direttiva @page.

Per creare una pagina in Blazor, creare un componente e aggiungere la direttiva @page per specificare la route per il componente. La direttiva @page accetta un solo parametro.

@page "/counter"

La cartella Shared

La cartella “Shared” contiene i file con il layout della pagina generalmente composto da un menu laterale (NavMenu.razor) e da una sezione centrale con i contenuti (MainLayout.razor).

Conclusioni

Come abbiamo visto ogni cartella ed ogni file ha una sua funzione per una corretta visualizzazione e funzionamento della nostra applicazione.