Validation
Conseil
Ce contenu est un extrait du livre électronique Modèles d’application d’entreprise avec .NET MAUI, disponible dans la .documentation .NET ou en tant que PDF téléchargeable gratuitement qui peut être lu hors connexion.
Toute application qui accepte une entrée des utilisateurs doit s’assurer que l’entrée est valide. Une application peut, par exemple, rechercher une entrée qui contient uniquement des caractères dans une plage particulière, est d’une certaine longueur ou correspond à un format particulier. Sans validation, un utilisateur peut fournir des données qui provoquent l’échec de l’application. Une validation appropriée applique des règles d’entreprise et peut empêcher un attaquant d’injecter des données malveillantes.
Dans le contexte du modèle modèle-vue-vue modèle (MVVM), un modèle de vue ou un modèle est souvent nécessaire pour effectuer la validation des données et signaler les erreurs de validation à la vue afin que l’utilisateur puisse les corriger. L’application multiplateforme eShop effectue une validation côté client synchrone des propriétés du modèle de vue et avertit l’utilisateur de toute erreur de validation en mettant en surbrillance le contrôle qui contient les données non valides et en affichant des messages d’erreur qui informent l’utilisateur de la raison pour laquelle les données ne sont pas valides. L’image ci-dessous montre les classes impliquées dans l’exécution de la validation dans l’application multiplateforme eShop.
Les propriétés de modèle d’affichage qui nécessitent une validation sont de type ValidatableObject<T>
, et chaque instance ValidatableObject<T>
a des règles de validation ajoutées à sa propriété Validations
. La validation est appelée à partir du modèle de vue en appelant la méthode Validate
de l’instance ValidatableObject<T>
, qui récupère les règles de validation et les exécute sur la propriété ValidatableObject<T>.Value
. Toutes les erreurs de validation sont placées dans la propriété Errors
de l’instance ValidatableObject<T>
, et la propriété IsValid
de l’instance ValidatableObject<T>
est mise à jour pour indiquer si la validation a réussi ou échoué. Le code suivant montre l’implémentation de l’élément ValidatableObject<T>
:
using CommunityToolkit.Mvvm.ComponentModel;
namespace eShop.Validations;
public class ValidatableObject<T> : ObservableObject, IValidity
{
private IEnumerable<string> _errors;
private bool _isValid;
private T _value;
public List<IValidationRule<T>> Validations { get; } = new();
public IEnumerable<string> Errors
{
get => _errors;
private set => SetProperty(ref _errors, value);
}
public bool IsValid
{
get => _isValid;
private set => SetProperty(ref _isValid, value);
}
public T Value
{
get => _value;
set => SetProperty(ref _value, value);
}
public ValidatableObject()
{
_isValid = true;
_errors = Enumerable.Empty<string>();
}
public bool Validate()
{
Errors = Validations
?.Where(v => !v.Check(Value))
?.Select(v => v.ValidationMessage)
?.ToArray()
?? Enumerable.Empty<string>();
IsValid = !Errors.Any();
return IsValid;
}
}
La notification de modification de propriété est fournie par la classe ObservableObject
. Par conséquent, un contrôle Entry
peut être lié à la propriété IsValid
de l’instance ValidatableObject<T>
dans la classe de modèle de vue pour être informé de la validité ou non des données entrées.
Spécification de règles de validation
Les règles de validation sont spécifiées en créant une classe qui dérive de l’interface IValidationRule<T>
, comme illustré dans l’exemple de code suivant :
public interface IValidationRule<T>
{
string ValidationMessage { get; set; }
bool Check(T value);
}
Cette interface spécifie qu’une classe de règle de validation doit fournir une méthode Check
booléenne utilisée pour effectuer la validation requise, ainsi qu’une propriété ValidationMessage
dont la valeur est le message d’erreur de validation qui s’affiche si la validation échoue.
L’exemple de code suivant montre la règle de validation IsNotNullOrEmptyRule<T>
utilisée pour effectuer la validation du nom d’utilisateur et du mot de passe entrés par l’utilisateur sur le LoginView
lors de l’utilisation de services fictifs dans l’application multiplateforme eShop :
public class IsNotNullOrEmptyRule<T> : IValidationRule<T>
{
public string ValidationMessage { get; set; }
public bool Check(T value) =>
value is string str && !string.IsNullOrWhiteSpace(str);
}
La méthode Check
retourne une valeur booléenne indiquant si l’argument value est null, vide ou se compose uniquement de caractères d’espace blanc.
Bien qu’elle ne soit pas utilisée par l’application multiplateforme eShop, l’exemple de code suivant montre une règle de validation pour la validation des adresses e-mail :
public class EmailRule<T> : IValidationRule<T>
{
private readonly Regex _regex = new(@"^([w.-]+)@([w-]+)((.(w){2,3})+)$");
public string ValidationMessage { get; set; }
public bool Check(T value) =>
value is string str && _regex.IsMatch(str);
}
La méthode Check
retourne une valeur booléenne indiquant si l’argument value est une adresse e-mail valide. Pour ce faire, recherchez la première occurrence du modèle d’expression régulière spécifié dans le constructeur Regex
dans l’argument value. Vous pouvez déterminer si le modèle d’expression régulière a été trouvé dans la chaîne d’entrée en vérifiant value
par rapport à Regex.IsMatch.
Notes
La validation de propriété peut parfois impliquer des propriétés dépendantes. Un exemple de propriétés dépendantes est lorsque l’ensemble de valeurs valides pour la propriété A dépend de la valeur particulière qui a été définie dans la propriété B. Pour vérifier que la valeur de la propriété A est l’une des valeurs autorisées, vous devez récupérer la valeur de la propriété B. En outre, lorsque la valeur de la propriété B change, la propriété A doit être revalidée.
Ajout de règles de validation à une propriété
Dans l’application multiplateforme eShop, affichez les propriétés de modèle qui nécessitent la validation sont déclarées comme de type ValidatableObject<T>
, où T
est le type des données à valider. L’exemple de code suivant montre un exemple de deux propriétés de ce type :
public ValidatableObject<string> UserName { get; private set; }
public ValidatableObject<string> Password { get; private set; }
Pour que la validation se produise, les règles de validation doivent être ajoutées à la collection Validations de chaque instance ValidatableObject<T>
, comme illustré dans l’exemple de code suivant :
private void AddValidations()
{
UserName.Validations.Add(new IsNotNullOrEmptyRule<string>
{
ValidationMessage = "A username is required."
});
Password.Validations.Add(new IsNotNullOrEmptyRule<string>
{
ValidationMessage = "A password is required."
});
}
Cette méthode ajoute la règle de validation IsNotNullOrEmptyRule<T>
à la collection Validations
de chaque instance ValidatableObject<T>
, en spécifiant des valeurs pour la propriété ValidationMessage
de la règle de validation, qui spécifie le message d’erreur de validation qui s’affichera en cas d’échec de la validation.
Déclenchement de la validation
L’approche de validation utilisée dans l’application multiplateforme eShop peut déclencher manuellement la validation d’une propriété et déclencher automatiquement la validation lorsqu’une propriété change.
Déclenchement manuel de la validation
La validation peut être déclenchée manuellement pour une propriété de modèle de vue. Par exemple, cela se produit dans l’application multiplateforme eShop lorsque l’utilisateur appuie sur le bouton Login
sur le LoginView
, lors de l’utilisation de services fictifs. Le délégué de commande appelle la méthode MockSignInAsync
dans le modèle de vue LoginViewModel
, qui appelle la validation en exécutant la méthode Validate
, ce qui est illustré dans l’exemple de code suivant :
private bool Validate()
{
bool isValidUser = ValidateUserName();
bool isValidPassword = ValidatePassword();
return isValidUser && isValidPassword;
}
private bool ValidateUserName()
{
return _userName.Validate();
}
private bool ValidatePassword()
{
return _password.Validate();
}
La méthode Validate
effectue la validation du nom d’utilisateur et du mot de passe entrés par l’utilisateur sur la vue LoginView
, en appelant la méthode Validate
sur chaque instance ValidatableObject<T>
. L’exemple de code suivant montre la méthode Validate
dans la classe ValidatableObject<T>
:
public bool Validate()
{
Errors = _validations
?.Where(v => !v.Check(Value))
?.Select(v => v.ValidationMessage)
?.ToArray()
?? Enumerable.Empty<string>();
IsValid = !Errors.Any();
return IsValid;
}
Cette méthode récupère toutes les règles de validation qui ont été ajoutées à la collection Validations
de l’objet. La méthode Check
pour chaque règle de validation récupérée est exécutée et la valeur de propriété ValidationMessage
pour toute règle de validation qui ne parvient pas à valider les données est ajoutée à la collection Errors
de l’instance ValidatableObject<T>
. Enfin, la propriété IsValid
est définie et sa valeur est retournée à la méthode appelante, indiquant si la validation a réussi ou échoué.
Déclenchement de la validation lorsque les propriétés changent
La validation est également déclenchée automatiquement chaque fois qu’une propriété liée change. Par exemple, lorsqu’une liaison bidirectionnelle dans la vue LoginView
définit la propriété UserName
ou Password
, la validation est déclenchée. L’exemple de code suivant montre comment cela se produit :
<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
<Entry.Behaviors>
<behaviors:EventToCommandBehavior
EventName="TextChanged"
Command="{Binding ValidateUserNameCommand}" />
</Entry.Behaviors>
</Entry>
Le contrôle Entry
est lié à la propriété UserName.Value
de l’instance ValidatableObject<T>
et une instance EventToCommandBehavior
est ajoutée à la collection Behaviors
du contrôle. Ce comportement exécute la commande ValidateUserNameCommand
en réponse à l’événement TextChanged
déclenché sur l’Entry
, qui est déclenché lorsque le texte dans l’Entry
change. À son tour, le délégué ValidateUserNameCommand
exécute la méthode ValidateUserName
, qui exécute la méthode Validate
sur l’instance ValidatableObject<T>
. Par conséquent, chaque fois que l’utilisateur entre un caractère dans le contrôle Entry
pour le nom d’utilisateur, la validation des données entrées est effectuée.
Affichage des erreurs de validation
L’application multiplateforme eShop avertit l’utilisateur de toute erreur de validation en mettant en surbrillance le contrôle qui contient les données non valides avec un arrière-plan rouge et en affichant un message d’erreur qui informe l’utilisateur de la raison pour laquelle les données ne sont pas valides sous le contrôle contenant les données non valides. Lorsque les données non valides sont corrigées, l’arrière-plan revient à l’état par défaut et le message d’erreur est supprimé. L’image ci-dessous montre LoginView
dans l’application multiplateforme eShop lorsque des erreurs de validation sont présentes.
Mise en surbrillance d’un contrôle qui contient des données non valides
.NET MAUI offre un certain nombre de façons de présenter des informations de validation aux utilisateurs finaux, mais l’une des méthodes les plus simples consiste à utiliser Triggers
. Triggers
fournit un moyen de modifier l’état de nos contrôles, généralement pour l’apparence, en fonction d’un événement ou d’une modification de données qui se produit pour un contrôle. Pour la validation, nous allons utiliser un DataTrigger
qui écoutera les modifications générées à partir d’une propriété liée et répondra aux modifications. Les contrôles Entry
sur la vue LoginView
sont configurés à l’aide du code suivant :
<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
<Entry.Style>
<OnPlatform x:TypeArguments="Style">
<On Platform="iOS, Android" Value="{StaticResource EntryStyle}" />
<On Platform="WinUI" Value="{StaticResource WinUIEntryStyle}" />
</OnPlatform>
</Entry.Style>
<Entry.Behaviors>
<mct:EventToCommandBehavior
EventName="TextChanged"
Command="{Binding ValidateCommand}" />
</Entry.Behaviors>
<Entry.Triggers>
<DataTrigger
TargetType="Entry"
Binding="{Binding UserName.IsValid}"
Value="False">
<Setter Property="BackgroundColor" Value="{StaticResource ErrorColor}" />
</DataTrigger>
</Entry.Triggers>
</Entry>
DataTrigger
spécifie les propriétés suivantes :
Propriété | Description |
---|---|
TargetType |
Type de contrôle auquel appartient le déclencheur. |
Binding |
Balisage de données Binding qui fournira des notifications de modification et une valeur pour la condition de déclencheur. |
Value |
Valeur de données à spécifier quand la condition du déclencheur a été remplie. |
Pour cette Entry
, nous allons écouter les modifications apportées à la propriété LoginViewModel.UserName.IsValid
. Chaque fois que cette propriété déclenche une modification, la valeur est comparée à la propriété Value
définie dans DataTrigger
. Si les valeurs sont égales, la condition de déclencheur est remplie et tous les objets Setter
fournis à DataTrigger
seront exécutés. Ce contrôle a un objet unique Setter
qui met à jour la propriété BackgroundColor
vers une couleur personnalisée définie à l’aide du balisage StaticResource
. Lorsqu’une condition Trigger
n’est plus remplie, le contrôle rétablit les propriétés définies par l’objet Setter
à leur état précédent. Pour plus d’informations sur Triggers
, consultez .NET MAUI Docs : Déclencheurs.
Affichage de messages d’erreur
L’interface utilisateur affiche des messages d’erreur de validation dans les contrôles Label sous chaque contrôle dont la validation des données a échoué. L’exemple de code suivant montre l’étiquette Label
qui affiche un message d’erreur de validation, si l’utilisateur n’a pas entré de nom d’utilisateur valide :
<Label
Text="{Binding UserName.Errors, Converter={StaticResource FirstValidationErrorConverter}"
Style="{StaticResource ValidationErrorLabelStyle}" />
Chaque étiquette est liée à la propriété Errors
de l’objet de modèle de vue en cours de validation. La propriété Errors
est fournie par la classe ValidatableObject<T>
et est de type IEnumerable<string>
. Étant donné que la propriété Errors
peut contenir plusieurs erreurs de validation, l’instance FirstValidationErrorConverter
est utilisée pour récupérer la première erreur de la collection pour affichage.
Résumé
L’application multiplateforme eShop effectue une validation synchrone côté client des propriétés du modèle d’affichage et avertit l’utilisateur des erreurs de validation en mettant en évidence le contrôle qui contient les données non valides et en affichant des messages d’erreur qui informent l’utilisateur de la raison pour laquelle les données ne sont pas valides.
Les propriétés de modèle d’affichage qui nécessitent une validation sont de type ValidatableObject<T>
, et chaque instance ValidatableObject<T>
a des règles de validation ajoutées à sa propriété Validations
. La validation est appelée à partir du modèle de vue en appelant la méthode Validate
de l’instance ValidatableObject<T>
, qui récupère les règles de validation et les exécute sur la propriété Value ValidatableObject<T>
. Toutes les erreurs de validation sont placées dans la propriété Errors
de l’instance ValidatableObject<T>
, et la propriété IsValid de l’instance ValidatableObject<T>
est mise à jour pour indiquer si la validation a réussi ou échoué.