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.
dotnet --version pour vérifier).Fini la console noire ! Nous allons créer une application web complète.
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.
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 est un framework orienté composants. Contrairement aux pages web classiques, tout est un composant réutilisable :
<MonBouton/>)
Exemple : MainLayout.razor est un composant qui contient
NavMenu.razor
(autre composant) + le contenu de chaque page.
dotnet watch
Note : La commande watch est magique. Elle relance le site automatiquement à
chaque
sauvegarde (Ctrl+S).
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;
}
Dans le code, changez IsSystemOK à false et sauvegardez.
❓ Question : Que se passe-t-il dans le navigateur ?
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>
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 !";
}
}
Cliquez plusieurs fois sur le bouton. Regardez l'icône de rafraîchissement de votre navigateur.
❓ Question : La page se recharge-t-elle ?
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 }
};
}
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 :
Celsius = (Fahrenheit - 32) × 5 / 9🔧 Démarche à suivre :
Components/Pages/Converter.razor avec la directive
@page "/converter"
TemperatureF de type double dans le bloc
@code
<input type="number"> lié à cette
variable avec @bind
✅ Travail demandé :
NavMenu.razor pour accéder à cette page@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;
}
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 :
Components/Pages/Logs.razor avec
@page "/logs"
SystemLogs dans le bloc @code@foreach pour parcourir la listeclass="@(condition ? "classe1" : "classe2")"
✅ Travail demandé :
<li>text-danger (rouge)text-success (vert)<h3>Journal Système</h3>
<ul>
@foreach (var log in SystemLogs)
{
<li class="@(log.Contains("Erreur") ? "text-danger" : "text-success")">
@log
</li>
}
</ul>
@page "/url" définit l'adresse.
@ permet de basculer du HTML au C#.@onclick="MaMethode" remplace le JavaScript.
@bind="MaVariable" lie un
champ de saisie à une
variable.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.
dotnet --version to verify).No more black console! We are going to create a complete web application.
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.
Figure: Blazor Web App Project Structure (.NET 10)
📁 Project Elements Description:
| Element | Description |
|---|---|
dotnet watch
Note: The watch command is magic. It automatically reloads the site on every save
(Ctrl+S).
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;
}
In the code, change IsSystemOK to false and save.
❓ Question: What happens in the browser?
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>
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!";
}
}
Click the button multiple times. Look at the refresh icon in your browser.
❓ Question: Does the page reload?
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 }
};
}
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:
Celsius = (Fahrenheit - 32) × 5 / 9🔧 Step-by-step Guide:
Components/Pages/Converter.razor with the directive
@page "/converter"
TemperatureF variable of type double in the @code block
<input type="number"> field bound to this variable with
@bind
✅ Required Work:
NavMenu.razor to access this page@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;
}
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:
Components/Pages/Logs.razor with @page "/logs"
SystemLogs list into the @code block@foreach to iterate through the listclass="@(condition ? "class1" : "class2")"
✅ Required Work:
<li> tagtext-danger class (red)text-success class (green)<h3>System Journal</h3>
<ul>
@foreach (var log in SystemLogs)
{
<li class="@(log.Contains("Error") ? "text-danger" : "text-success")">
@log
</li>
}
</ul>
@page "/url" defines the address.@ symbol switches from HTML to C#.@onclick="MyMethod" replaces
JavaScript.@bind="MyVariable" links an input
field to a variable.