Module : Programmation .Net C#
Durée : 30 min (Synthèse Théorique)
Pré-requis : Avoir réalisé le TP 7.
En développement Web traditionnel, un formulaire utilise la balise
<form action="/save" method="POST">. Lors du clic sur "Envoyer", la page entière est
rechargée et les données sont envoyées au serveur.
Dans une architecture Blazor (SPA), la page ne se recharge jamais. La logique C#
s'exécute directement en mémoire. Blazor remplace la balise <form> par un composant
intelligent : <EditForm>.
<EditForm> :Pour lier une variable C# à un champ visuel, on utilise la directive
@bind-Value (Liaison à double sens).
Blazor fournit des composants d'interface spécifiques qui remplacent les balises HTML standard pour
gérer le typage fort de C# :
| HTML Classique | Composant Blazor | Utilisation C# correspondante |
|---|---|---|
<input type="text"> |
<InputText> |
string (Texte court) |
<textarea> |
<InputTextArea> |
string (Texte long / Description)
|
<input type="number"> |
<InputNumber> |
int, double,
decimal |
<input type="date"> |
<InputDate> |
DateTime |
<input type="checkbox"> |
<InputCheckbox> |
bool (Vrai/Faux) |
<select> |
<InputSelect> |
Enum ou Clés étrangères
(int) |
<input type="radio"> |
<InputRadioGroup> +
<InputRadio> |
Choix unique (Ex: Genre,
Statut) |
Exemple de syntaxe pour les Radio Buttons :
<InputRadioGroup @bind-Value="monCapteur.Status">
<InputRadio Value="1" /> Actif
<InputRadio Value="0" /> Inactif
</InputRadioGroup>
En tant qu'ingénieur Data, la qualité des données entrantes est primordiale. Blazor utilise un système en 3 parties pour garantir cette intégrité.
Les règles métier sont définies une seule fois, directement dans la classe C#, via les Data Annotations
(namespace System.ComponentModel.DataAnnotations).
Voici les annotations standards les plus utilisées pour la validation :
| Annotation | Rôle | Exemple de code | Message d'erreur type |
|---|---|---|---|
[Required] |
Interdit les valeurs vides ou nulles. | [Required(ErrorMessage="Requis")] |
Le champ est obligatoire. |
[StringLength] |
Limite la taille d'un texte (Max et Min). | [StringLength(50, MinimumLength=3)] |
Doit faire entre 3 et 50 caractères. |
[Range] |
Borne une valeur numérique ou une date. | [Range(0.0, 100.0)] |
La valeur doit être entre 0 et 100. |
[EmailAddress] |
Vérifie le format d'un email. | [EmailAddress] |
Format d'email invalide. |
[Phone] |
Vérifie le format d'un numéro de téléphone. | [Phone] |
Numéro de téléphone invalide. |
[Url] |
Vérifie qu'il s'agit d'un lien web valide. | [Url] |
L'URL fournie n'est pas valide. |
[Compare] |
Vérifie que deux champs sont identiques. | [Compare("Password")] |
Les mots de passe ne correspondent pas. |
[RegularExpression] |
Validation avancée sur mesure via Regex. | [RegularExpression(@"^[A-Z]{3}\d{2}$")] |
Le format attendu est ABC12. |
<DataAnnotationsValidator>)C'est le "moteur" invisible. Placé à l'intérieur de l'<EditForm>, il lit
automatiquement les attributs (ci-dessus) de votre classe C#.
<ValidationMessage>)Affiche le texte de l'erreur en rouge juste en dessous du champ concerné.
Le flux complet :
<EditForm Model="monCapteur" OnValidSubmit="SaveData">
<DataAnnotationsValidator /> <!-- Active le moteur -->
<InputText @bind-Value="monCapteur.Name" /> <!-- Saisie -->
<ValidationMessage For="@(() => monCapteur.Name)" /> <!-- Affiche l'erreur -->
<button type="submit">Sauvegarder</button>
</EditForm>
L'<EditForm> expose des événements pour gérer le clic sur le bouton "Submit" :
OnValidSubmit (Recommandé) : La méthode C# n'est appelée que
si toutes les règles de validation sont respectées.OnInvalidSubmit : Appelée si le formulaire contient des erreurs (utile
pour afficher un log d'erreur global).OnSubmit : Appelée à chaque clic. Si vous utilisez
OnSubmit, la validation automatique est désactivée (vous devez la gérer manuellement).
Une erreur de débutant consiste à créer deux pages : CreateSensor.razor et
UpdateSensor.razor. C'est une duplication de code difficile à maintenir.
L'architecture professionnelle consiste à réutiliser le même composant grâce au
routage.
Comment ça marche ?
@page "/edit" (Création)
et @page "/edit/{Id:int}" (Modification).[Parameter] public int? Id { get; set; }
Id est nul $\rightarrow$
currentSensor = new SensorData();
Id a une valeur $\rightarrow$
currentSensor = await Service.GetById(Id.Value);OnValidSubmit) :
Id est nul $\rightarrow$ INSERT (Add).Id a une valeur $\rightarrow$ UPDATE.Après avoir sauvegardé un formulaire, il faut rediriger l'utilisateur vers le tableau de bord. On utilise
le service intégré NavigationManager.
@inject NavigationManager NavManager
// Dans la méthode de sauvegarde :
NavManager.NavigateTo("/dashboard");
| Composant / Concept | Rôle principal |
|---|---|
<EditForm> |
Conteneur intelligent du formulaire. Gère la validation en mémoire. |
@bind-Value |
Synchronise la variable C# et le champ visuel en temps réel. |
InputText, InputTextArea,
InputRadio |
Composants Blazor optimisés et fortement typés remplaçant le HTML. |
DataAnnotationsValidator |
Moteur qui lit les règles ([Required],
[Range]) du modèle C#. |
ValidationMessage |
Affiche le message d'erreur spécifique à un champ. |
OnValidSubmit |
Événement déclenché uniquement si les données sont 100% valides. |
[Parameter] int? Id |
Permet d'unifier la Création et la Modification sur une seule et même page. |
Module: .Net C# Programming
Duration: 30 min (Theoretical Synthesis)
Prerequisites: Have completed LAB 7.
In traditional Web development, a form uses the <form action="/save" method="POST">
tag. Clicking "Submit" reloads the entire page and sends the data to the server.
In a Blazor (SPA) architecture, the page never reloads. C# logic executes directly in
memory. Blazor replaces the <form> tag with a smart component:
<EditForm>.
<EditForm>:To bind a C# variable to a visual field, we use the directive @bind-Value
(two-way binding).
Blazor provides specific UI components that replace standard HTML tags to handle C#'s strong typing:
| Classic HTML | Blazor Component | Corresponding C# Usage |
|---|---|---|
<input type="text"> |
<InputText> |
string (Short text) |
<textarea> |
<InputTextArea> |
string (Long text / Description) |
<input type="number"> |
<InputNumber> |
int, double,
decimal |
<input type="date"> |
<InputDate> |
DateTime |
<input type="checkbox"> |
<InputCheckbox> |
bool (True/False) |
<select> |
<InputSelect> |
Enum or Foreign Keys (int)
|
<input type="radio"> |
<InputRadioGroup> +
<InputRadio> |
Single choice (e.g., Gender,
Status) |
Syntax example for Radio Buttons:
<InputRadioGroup @bind-Value="mySensor.Status">
<InputRadio Value="1" /> Active
<InputRadio Value="0" /> Inactive
</InputRadioGroup>
As a Data Engineer, the quality of incoming data is critical. Blazor uses a 3-part system to ensure this integrity.
Business rules are defined only once, directly in the C# class, via Data Annotations
(System.ComponentModel.DataAnnotations namespace).
Here are the most commonly used standard annotations for validation:
| Annotation | Role | Code Example | Typical Error Message |
|---|---|---|---|
[Required] |
Forbids empty or null values. | [Required(ErrorMessage="Required")] |
The field is mandatory. |
[StringLength] |
Limits text size (Max and Min). | [StringLength(50, MinimumLength=3)] |
Must be between 3 and 50 characters. |
[Range] |
Bounds a numeric value or a date. | [Range(0.0, 100.0)] |
Value must be between 0 and 100. |
[EmailAddress] |
Verifies email format. | [EmailAddress] |
Invalid email format. |
[Phone] |
Verifies phone number format. | [Phone] |
Invalid phone number. |
[Url] |
Verifies it is a valid web link. | [Url] |
The provided URL is not valid. |
[Compare] |
Verifies that two fields are identical. | [Compare("Password")] |
Passwords do not match. |
[RegularExpression] |
Advanced custom validation via Regex. | [RegularExpression(@"^[A-Z]{3}\d{2}$")] |
Expected format is ABC12. |
<DataAnnotationsValidator>)This is the invisible "engine". Placed inside the <EditForm>, it automatically reads
the attributes (above) from your C# class.
<ValidationMessage>)Displays the error text in red just below the relevant field.
The complete flow:
<EditForm Model="mySensor" OnValidSubmit="SaveData">
<DataAnnotationsValidator /> <!-- Activates the engine -->
<InputText @bind-Value="mySensor.Name" /> <!-- Input -->
<ValidationMessage For="@(() => mySensor.Name)" /> <!-- Displays error -->
<button type="submit">Save</button>
</EditForm>
The <EditForm> exposes events to handle the click on the "Submit" button:
OnValidSubmit (Recommended): The C# method is called only
if all validation rules are met.OnInvalidSubmit: Called if the form contains errors (useful for
displaying a global error log).OnSubmit: Called on every click. If you use OnSubmit,
automatic validation is disabled (you must handle it manually).A beginner's mistake is creating two pages: CreateSensor.razor and
UpdateSensor.razor. This is duplicate code that is difficult to maintain.
The professional architecture consists of reusing the same component thanks to routing.
How does it work?
@page "/edit" (Creation) and
@page "/edit/{Id:int}" (Modification).[Parameter] public int? Id { get; set; }
Id is null $\rightarrow$
currentSensor = new SensorData();
Id has a value $\rightarrow$
currentSensor = await Service.GetById(Id.Value);OnValidSubmit):
Id is null $\rightarrow$ INSERT (Add).Id has a value $\rightarrow$ UPDATE.After saving a form, the user must be redirected to the dashboard. The built-in
NavigationManager service is used for this.
@inject NavigationManager NavManager
// Inside the save method:
NavManager.NavigateTo("/dashboard");
| Component / Concept | Main Role |
|---|---|
<EditForm> |
Smart form container. Handles in-memory validation. |
@bind-Value |
Synchronizes the C# variable and visual field in real time. |
InputText, InputTextArea,
InputRadio |
Optimized and strongly typed Blazor components replacing HTML. |
DataAnnotationsValidator |
Engine that reads rules ([Required],
[Range]) from the C# model. |
ValidationMessage |
Displays the specific error message for a field. |
OnValidSubmit |
Event triggered only if the data is 100% valid. |
[Parameter] int? Id |
Allows unifying Creation and Modification on a single page. |