🌐
🔍 100%
👁️

TP 3 : Application Web Blazor avec .NET 10

Module : Programmation .Net C#

Niveau : 4ème Génie Informatique

Objectif : Comprendre l'architecture d'une Application Web Blazor avec .NET 10, créer sa première page interactive et maîtriser le mélange HTML/C# (Razor) sans utiliser de JavaScript.

Pré-requis

Activité 1 : Génération et Analyse du Projet

Fini la console noire ! Nous allons créer une application web complète.

1. Création

Dans votre terminal, lancez la commande suivante :

# Générer une nouvelle Application Web Blazor (.NET 10)
dotnet new blazor -n DashboardData
cd DashboardData
code .
Note .NET 10 : Le template blazor crée une Application Web Blazor unifiée qui supporte le rendu côté serveur (SSR), le mode interactif Server, et WebAssembly. C'est le nouveau modèle recommandé par Microsoft.

2. Exploration

Structure du projet Blazor Web App

Figure : Structure d'une Application Web Blazor (.NET 10)

📁 Description des éléments du projet :

Élément Description
Components/ Dossier principal contenant tous les composants Razor de l'application.
Components/Layout/ Contient les layouts (mise en page) : MainLayout.razor (structure globale) et NavMenu.razor (menu de navigation).
Components/Pages/ Contient les pages de l'application. Chaque fichier .razor avec @page devient une route accessible.
App.razor Composant racine de l'application, définit le mode de rendu (Server/WebAssembly).
Routes.razor Configure le routage de l'application.
_Imports.razor Contient les directives @using partagées par tous les composants.
wwwroot/ Fichiers statiques (CSS, JS, images) accessibles publiquement.
Program.cs Point d'entrée de l'application. Configure les services et le pipeline HTTP.
appsettings.json Fichier de configuration (chaînes de connexion, paramètres, etc.).

💡 Blazor : Architecture orientée Composants

Blazor est un framework orienté composants. Contrairement aux pages web classiques, tout est un composant réutilisable :

Exemple : MainLayout.razor est un composant qui contient NavMenu.razor (autre composant) + le contenu de chaque page.

3. Lancement (Hot Reload)

dotnet watch

Note : La commande watch est magique. Elle relance le site automatiquement à chaque sauvegarde (Ctrl+S).

Activité 2 : Votre première page "Razor"

Nous allons créer une page dédiée à notre futur Dashboard. Dans le dossier Components/Pages, créez un fichier nommé MyDashboard.razor.

@page "/dashboard"
@rendermode InteractiveServer

<PageTitle>Mon Dashboard Data</PageTitle>

<h1>Tableau de Bord</h1>

<div class="alert alert-info">
    Bienvenue sur l'interface de pilotage.
    Nous sommes le : <strong>@DateTime.Now.ToString("dd MMMM yyyy")</strong>
</div>

<p>
    Status du système : 
    <!-- Condition C# directement dans le HTML -->
    @if (IsSystemOK)
    {
        <span class="badge bg-success">Opérationnel</span>
    }
    else
    {
        <span class="badge bg-danger">Erreur Critique</span>
    }
</p>

@code {
    // Zone C# : Ici on déclare l'état de la page
    private bool IsSystemOK = true;
}

🔎 Défi Rapide

Dans le code, changez IsSystemOK à false et sauvegardez.

❓ Question : Que se passe-t-il dans le navigateur ?

Activité 3 : Navigation et Menu

Votre page est accessible via l'URL, mais elle n'est pas dans le menu de gauche. Ouvrez Components/Layout/NavMenu.razor et ajoutez ce bloc :

<div class="nav-item px-3">
    <!-- NavLink gère la classe css 'active' automatiquement -->
    <NavLink class="nav-link" href="dashboard">
        <span class="bi bi-newspaper" aria-hidden="true"></span> Dashboard
    </NavLink>
</div>

Activité 4 : Interactivité (Le "Click")

C'est ici que Blazor brille. Vous allez rendre la page interactive sans écrire une seule ligne de JavaScript. Modifiez MyDashboard.razor :

<!-- @onclick remplace le onclick du JavaScript -->
<button class="btn btn-primary" @onclick="RefreshSystem">
    <span class="bi bi-arrow-repeat"></span> Actualiser le statut
</button>

<div class="mt-3 card card-body">
    Logs : @LastLog
</div>

@code {
    private bool IsSystemOK = true;
    private int RequestCount = 0;
    private string LastLog = "Rien à signaler";

    // Méthode C# standard qui sera appelée par le bouton
    private void RefreshSystem()
    {
        RequestCount++;
        var rnd = new Random();
        IsSystemOK = rnd.Next(0, 10) > 2; // 80% de chance d'être OK

        if (IsSystemOK)
            LastLog = $"Check {RequestCount} : Tout va bien.";
        else
            LastLog = $"Check {RequestCount} : ANOMALIE DÉTECTÉE !";
    }
}

🔎 Observation

Cliquez plusieurs fois sur le bouton. Regardez l'icône de rafraîchissement de votre navigateur.

❓ Question : La page se recharge-t-elle ?

Activité 5 : Intégration de Classes de Données

1. A la racine du projet, créez un dossier Models et une classe SensorData.cs :

namespace DashboardData.Models;

public class SensorData
{
    public string Name { get; set; }
    public double Value { get; set; }
}

2. Dans MyDashboard.razor, affichez une liste :

@using DashboardData.Models 

<table class="table table-striped">
    <thead>
        <tr>
            <th>Nom</th>
            <th>Valeur</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var sensor in Sensors)
        {
            <tr>
                <td>@sensor.Name</td>
                <td>@sensor.Value</td>
            </tr>
        }
    </tbody>
</table>

@code {
    // ... code précédent ...
    private List<SensorData> Sensors = new List<SensorData>
    {
        new SensorData { Name = "Temp_Salon", Value = 22.5 },
        new SensorData { Name = "Hum_Cuisine", Value = 45.0 },
        new SensorData { Name = "CO2_Bureau", Value = 800 }
    };
}

Exercices d'application (En autonomie)

Exercice 1 : Le Convertisseur de Température

📋 Objectif pédagogique

Maîtriser le binding bi-directionnel avec @bind pour synchroniser une variable C# avec un champ de saisie HTML en temps réel.

📌 Contexte : Vous devez créer une page de conversion de température Fahrenheit → Celsius.

📊 Données fournies :

🔧 Démarche à suivre :

  1. Créez une nouvelle page Components/Pages/Converter.razor avec la directive @page "/converter"
  2. Déclarez une variable TemperatureF de type double dans le bloc @code
  3. Ajoutez un champ <input type="number"> lié à cette variable avec @bind
  4. Affichez le résultat de la conversion en utilisant une expression Razor inline

✅ Travail demandé :

  1. Implémentez la page avec le code ci-dessous comme référence
  2. Ajoutez un lien dans NavMenu.razor pour accéder à cette page
  3. Bonus : Ajoutez la conversion inverse (Celsius → Fahrenheit) sur la même page
💡 Voir le code de référence
@page "/converter"
@rendermode InteractiveServer

<h3>Convertisseur de Température</h3>

<div class="mb-3">
    <label>Température en Fahrenheit :</label>
    <input type="number" class="form-control" @bind="TemperatureF" />
</div>

<div class="alert alert-success">
    Résultat en Celsius : <strong>@( Math.Round((TemperatureF - 32) * 5 / 9, 2) )</strong> °C
</div>

@code { 
    private double TemperatureF = 100; 
}

Exercice 2 : Le Simulateur de Logs Système

📋 Objectif pédagogique

Maîtriser les styles CSS dynamiques en utilisant des expressions ternaires dans les attributs class pour modifier l'apparence selon les données.

📌 Contexte : Vous devez afficher une liste de logs système où les erreurs apparaissent en rouge et les messages normaux en vert.

📊 Données fournies :

private List<string> SystemLogs = new()
{
    "10:00 - Démarrage du système",
    "10:05 - Erreur : Connexion base de données échouée",
    "10:06 - Reconnexion réussie",
    "10:15 - Erreur : Timeout API externe",
    "10:20 - Sauvegarde automatique effectuée"
};

🔧 Démarche à suivre :

  1. Créez une page Components/Pages/Logs.razor avec @page "/logs"
  2. Copiez la liste SystemLogs dans le bloc @code
  3. Utilisez @foreach pour parcourir la liste
  4. Appliquez une classe CSS conditionnelle avec l'opérateur ternaire : class="@(condition ? "classe1" : "classe2")"

✅ Travail demandé :

  1. Affichez chaque log dans une balise <li>
  2. Les logs contenant "Erreur" doivent avoir la classe text-danger (rouge)
  3. Les autres logs doivent avoir la classe text-success (vert)
  4. Bonus : Ajoutez un compteur affichant "X erreurs sur Y logs"
💡 Voir le code de référence
<h3>Journal Système</h3>

<ul>
    @foreach (var log in SystemLogs)
    {
        <li class="@(log.Contains("Erreur") ? "text-danger" : "text-success")">
            @log
        </li>
    }
</ul>

Synthèse du TP 3

LAB 3: Blazor Web App with .NET 10

Module: .Net C# Programming

Level: 4th Year Computer Engineering

Objective: Understand Blazor Web App architecture with .NET 10, create your first interactive page, and master HTML/C# mixing (Razor) without JavaScript.

Prerequisites

Activity 1: Generation and Project Analysis

No more black console! We are going to create a complete web application.

1. Creation

In your terminal, run the following command:

# Generate a new Blazor Web App (.NET 10)
dotnet new blazor -n DashboardData
cd DashboardData
code .
.NET 10 Note: The blazor template creates a unified Blazor Web App that supports Server-Side Rendering (SSR), Interactive Server mode, and WebAssembly. This is Microsoft's new recommended model.

2. Exploration

Blazor Web App Project Structure

Figure: Blazor Web App Project Structure (.NET 10)

📁 Project Elements Description:

💡 Blazor: Component-Oriented Architecture

Blazor is a component-oriented framework. Unlike traditional web pages, everything is a reusable component:

Example: MainLayout.razor is a component that contains NavMenu.razor (another component) + the content of each page.

Element Description

3. Launch (Hot Reload)

dotnet watch

Note: The watch command is magic. It automatically reloads the site on every save (Ctrl+S).

Activity 2: Your First "Razor" Page

We will create a page dedicated to our future Dashboard. In the Components/Pages folder, create a file named MyDashboard.razor.

@page "/dashboard"
@rendermode InteractiveServer

<PageTitle>My Data Dashboard</PageTitle>

<h1>Dashboard</h1>

<div class="alert alert-info">
    Welcome to the control interface.
    Today is: <strong>@DateTime.Now.ToString("dd MMMM yyyy")</strong>
</div>

<p>
    System Status: 
    <!-- C# Condition directly in HTML -->
    @if (IsSystemOK)
    {
        <span class="badge bg-success">Operational</span>
    }
    else
    {
        <span class="badge bg-danger">Critical Error</span>
    }
</p>

@code {
    // C# Zone: Here we declare the page state
    private bool IsSystemOK = true;
}

🔎 Quick Challenge

In the code, change IsSystemOK to false and save.

❓ Question: What happens in the browser?

Activity 3: Navigation and Menu

Your page is accessible via URL, but it's not in the left menu. Open Components/Layout/NavMenu.razor and add this block:

<div class="nav-item px-3">
    <!-- NavLink manages the 'active' css class automatically -->
    <NavLink class="nav-link" href="dashboard">
        <span class="bi bi-newspaper" aria-hidden="true"></span> Dashboard
    </NavLink>
</div>

Activity 4: Interactivity (The "Click")

This is where Blazor shines. You will make the page interactive without writing a single line of JavaScript. Modify MyDashboard.razor:

<!-- @onclick replaces JavaScript onclick -->
<button class="btn btn-primary" @onclick="RefreshSystem">
    <span class="bi bi-arrow-repeat"></span> Refresh Status
</button>

<div class="mt-3 card card-body">
    Logs: @LastLog
</div>

@code {
    private bool IsSystemOK = true;
    private int RequestCount = 0;
    private string LastLog = "Nothing to report";

    // Standard C# method called by the button
    private void RefreshSystem()
    {
        RequestCount++;
        var rnd = new Random();
        IsSystemOK = rnd.Next(0, 10) > 2; // 80% chance of being OK

        if (IsSystemOK)
            LastLog = $"Check {RequestCount} : All good.";
        else
            LastLog = $"Check {RequestCount} : ANOMALY DETECTED!";
    }
}

🔎 Observation

Click the button multiple times. Look at the refresh icon in your browser.

❓ Question: Does the page reload?

Activity 5: Integrating Data Classes

1. At the project root, create a Models folder and a SensorData.cs class.

namespace DashboardData.Models;

public class SensorData
{
    public string Name { get; set; }
    public double Value { get; set; }
}

2. In MyDashboard.razor, display a list:

@using DashboardData.Models 

<table class="table table-striped">
    <thead>
        <tr>
            <th>Name</th>
            <th>Value</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var sensor in Sensors)
        {
            <tr>
                <td>@sensor.Name</td>
                <td>@sensor.Value</td>
            </tr>
        }
    </tbody>
</table>

@code {
    // ... previous code ...
    private List<SensorData> Sensors = new List<SensorData>
    {
        new SensorData { Name = "Temp_Salon", Value = 22.5 },
        new SensorData { Name = "Hum_Cuisine", Value = 45.0 },
        new SensorData { Name = "CO2_Bureau", Value = 800 }
    };
}

Application Exercises (Autonomous)

Exercise 1: Temperature Converter

📋 Learning Objective

Master two-way binding with @bind to synchronize a C# variable with an HTML input field in real-time.

📌 Context: You need to create a temperature conversion page (Fahrenheit → Celsius).

📊 Provided Data:

🔧 Step-by-step Guide:

  1. Create a new page Components/Pages/Converter.razor with the directive @page "/converter"
  2. Declare a TemperatureF variable of type double in the @code block
  3. Add an <input type="number"> field bound to this variable with @bind
  4. Display the conversion result using an inline Razor expression

✅ Required Work:

  1. Implement the page using the code below as reference
  2. Add a link in NavMenu.razor to access this page
  3. Bonus: Add reverse conversion (Celsius → Fahrenheit) on the same page
💡 View reference code
@page "/converter"
@rendermode InteractiveServer

<h3>Temperature Converter</h3>

<div class="mb-3">
    <label>Temperature in Fahrenheit:</label>
    <input type="number" class="form-control" @bind="TemperatureF" />
</div>

<div class="alert alert-success">
    Result in Celsius: <strong>@( Math.Round((TemperatureF - 32) * 5 / 9, 2) )</strong> °C
</div>

@code { 
    private double TemperatureF = 100; 
}

Exercise 2: System Log Simulator

📋 Learning Objective

Master dynamic CSS styling using ternary expressions in class attributes to modify appearance based on data.

📌 Context: You need to display a list of system logs where errors appear in red and normal messages appear in green.

📊 Provided Data:

private List<string> SystemLogs = new()
{
    "10:00 - System startup",
    "10:05 - Error: Database connection failed",
    "10:06 - Reconnection successful",
    "10:15 - Error: External API timeout",
    "10:20 - Automatic backup completed"
};

🔧 Step-by-step Guide:

  1. Create a page Components/Pages/Logs.razor with @page "/logs"
  2. Copy the SystemLogs list into the @code block
  3. Use @foreach to iterate through the list
  4. Apply a conditional CSS class using the ternary operator: class="@(condition ? "class1" : "class2")"

✅ Required Work:

  1. Display each log in an <li> tag
  2. Logs containing "Error" must have the text-danger class (red)
  3. Other logs must have the text-success class (green)
  4. Bonus: Add a counter showing "X errors out of Y logs"
💡 View reference code
<h3>System Journal</h3>

<ul>
    @foreach (var log in SystemLogs)
    {
        <li class="@(log.Contains("Error") ? "text-danger" : "text-success")">
            @log
        </li>
    }
</ul>

LAB 3 Synthesis

🎙️ Sélectionner une voix

🎙️ Select a voice