Delen via


Validatie

Tip

Deze inhoud is een fragment uit het eBook, Enterprise Application Patterns Using .NET MAUI, beschikbaar op .NET Docs of als een gratis downloadbare PDF die offline kan worden gelezen.

Enterprise Application Patterns Using .NET MAUI eBook cover thumbnail.

Elke app die invoer van gebruikers accepteert, moet ervoor zorgen dat de invoer geldig is. Een app kan bijvoorbeeld controleren op invoer die alleen tekens in een bepaald bereik bevat, een bepaalde lengte heeft of overeenkomt met een bepaalde indeling. Zonder validatie kan een gebruiker gegevens opgeven die ervoor zorgen dat de app mislukt. De juiste validatie dwingt bedrijfsregels af en kan helpen voorkomen dat een aanvaller schadelijke gegevens injecteert.

In de context van het MVVM-patroon (Model-View-ViewModel) is vaak een weergavemodel of model vereist om gegevensvalidatie uit te voeren en eventuele validatiefouten aan te geven aan de weergave, zodat de gebruiker deze kan corrigeren. De eShop-app voor meerdere platforms voert synchrone clientvalidatie uit van weergavemodeleigenschappen en informeert de gebruiker over validatiefouten door het besturingselement met de ongeldige gegevens te markeren en door foutberichten weer te geven die de gebruiker informeren waarom de gegevens ongeldig zijn. In de onderstaande afbeelding ziet u de klassen die betrokken zijn bij het uitvoeren van validatie in de eShop-app voor meerdere platforms.

Validatieklassen in de eShop-app voor meerdere platforms.

Modeleigenschappen weergeven waarvoor validatie is vereist, zijn van het type ValidatableObject<T>en voor elk ValidatableObject<T> exemplaar zijn validatieregels toegevoegd aan de Validations eigenschap. Validatie wordt aangeroepen vanuit het weergavemodel door de Validate methode van het ValidatableObject<T> exemplaar aan te roepen, waarmee de validatieregels worden opgehaald en uitgevoerd op basis van de ValidatableObject<T>.Value eigenschap. Validatiefouten worden in de Errors eigenschap van het ValidatableObject<T> exemplaar geplaatst en de IsValid eigenschap van het ValidatableObject<T> exemplaar wordt bijgewerkt om aan te geven of de validatie is geslaagd of mislukt. De volgende code toont de implementatie van: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;
    }
}

Melding over het wijzigen van eigenschappen wordt geleverd door de ObservableObject klasse, zodat een Entry besturingselement kan worden gebonden aan de eigenschap van ValidatableObject<T> het IsValid exemplaar in de weergavemodelklasse om te worden gewaarschuwd of de ingevoerde gegevens geldig zijn.

Validatieregels opgeven

Validatieregels worden opgegeven door een klasse te maken die is afgeleid van de IValidationRule<T> interface, die wordt weergegeven in het volgende codevoorbeeld:

public interface IValidationRule<T>
{
    string ValidationMessage { get; set; }
    bool Check(T value);
}

Deze interface geeft aan dat een validatieregelklasse een booleaanse Check methode moet opgeven die wordt gebruikt om de vereiste validatie uit te voeren en een ValidationMessage eigenschap waarvan de waarde het validatiefoutbericht is dat wordt weergegeven als de validatie mislukt.

In het volgende codevoorbeeld ziet u de IsNotNullOrEmptyRule<T> validatieregel, die wordt gebruikt voor het uitvoeren van validatie van de gebruikersnaam en het wachtwoord die de gebruiker heeft ingevoerd bij LoginView het gebruik van mock-services in de eShop-app met meerdere platforms:

public class IsNotNullOrEmptyRule<T> : IValidationRule<T>
{
    public string ValidationMessage { get; set; }

    public bool Check(T value) =>
        value is string str && !string.IsNullOrWhiteSpace(str);
}

De Check methode retourneert een Booleaanse waarde die aangeeft of het waardeargument null, leeg of alleen uit witruimtetekens bestaat.

Hoewel deze niet wordt gebruikt door de eShop-app met meerdere platforms, toont het volgende codevoorbeeld een validatieregel voor het valideren van e-mailadressen:

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);
}

De Check methode retourneert een Booleaanse waarde die aangeeft of het waardeargument een geldig e-mailadres is. Dit wordt bereikt door te zoeken naar het waardeargument voor het eerste exemplaar van het reguliere expressiepatroon dat is opgegeven in de Regex constructor. Of het reguliere expressiepatroon in de invoertekenreeks is gevonden, kan worden bepaald door het value tegen Regex.IsMatchte controleren.

Notitie

Validatie van eigenschappen kan soms afhankelijke eigenschappen omvatten. Een voorbeeld van afhankelijke eigenschappen is wanneer de set geldige waarden voor eigenschap A afhankelijk is van de specifieke waarde die is ingesteld in eigenschap B. Als u wilt controleren of de waarde van eigenschap A een van de toegestane waarden is, moet u de waarde van eigenschap B ophalen. Bovendien moet eigenschap A opnieuw worden gevalideerd wanneer de waarde van eigenschap B wordt gewijzigd.

Validatieregels toevoegen aan een eigenschap

In de eShop-app voor meerdere platforms worden modeleigenschappen weergegeven waarvoor validatie is vereist, van het type ValidatableObject<T>, waarbij T het type gegevens is dat moet worden gevalideerd. In het volgende codevoorbeeld ziet u een voorbeeld van twee eigenschappen:

public ValidatableObject<string> UserName { get; private set; }
public ValidatableObject<string> Password { get; private set; }

Validatieregels moeten worden toegevoegd aan de verzameling Validaties van elk ValidatableObject<T> exemplaar, zoals wordt weergegeven in het volgende codevoorbeeld:

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." 
    });
}

Met deze methode wordt de IsNotNullOrEmptyRule<T> validatieregel toegevoegd aan de Validations verzameling van elk ValidatableObject<T> exemplaar, waarbij waarden worden opgegeven voor de eigenschap van ValidationMessage de validatieregel, waarmee het validatiefoutbericht wordt opgegeven dat wordt weergegeven als de validatie mislukt.

Validatie activeren

De validatiebenadering die wordt gebruikt in de eShop-app voor meerdere platforms kan handmatig validatie van een eigenschap activeren en automatisch validatie activeren wanneer een eigenschap wordt gewijzigd.

Validatie handmatig activeren

Validatie kan handmatig worden geactiveerd voor een weergavemodeleigenschap. Dit gebeurt bijvoorbeeld in de eShop-app met meerdere platforms wanneer de gebruiker op de knop op de Login LoginViewknop tikt bij het gebruik van mockservices. De gemachtigde van de opdracht roept de MockSignInAsync methode aan in de LoginViewModel, die validatie aanroept door de Validate methode uit te voeren, die wordt weergegeven in het volgende codevoorbeeld:

private bool Validate()
{
    bool isValidUser = ValidateUserName();
    bool isValidPassword = ValidatePassword();
    return isValidUser && isValidPassword;
}

private bool ValidateUserName()
{
    return _userName.Validate();
}

private bool ValidatePassword()
{
    return _password.Validate();
}

De Validate methode voert de validatie uit van de gebruikersnaam en het wachtwoord die door de gebruiker op de LoginViewgebruiker zijn ingevoerd, door de Validate methode op elk ValidatableObject<T> exemplaar aan te roepen. In het volgende codevoorbeeld ziet u de Validate methode uit de ValidatableObject<T> klasse:

public bool Validate()
{
    Errors = _validations
        ?.Where(v => !v.Check(Value))
        ?.Select(v => v.ValidationMessage)
        ?.ToArray()
        ?? Enumerable.Empty<string>();

    IsValid = !Errors.Any();

    return IsValid;
}

Met deze methode worden validatieregels opgehaald die zijn toegevoegd aan de verzameling van Validations het object. De Check methode voor elke opgehaalde validatieregel wordt uitgevoerd en de ValidationMessage eigenschapswaarde voor een validatieregel die de gegevens niet valideert, wordt toegevoegd aan de Errors verzameling van het ValidatableObject<T> exemplaar. Ten slotte wordt de eigenschap ingesteld en wordt de IsValid waarde geretourneerd naar de aanroepmethode, waarmee wordt aangegeven of de validatie is geslaagd of mislukt.

Validatie activeren wanneer eigenschappen worden gewijzigd

Validatie wordt ook automatisch geactiveerd wanneer een afhankelijke eigenschap wordt gewijzigd. Wanneer bijvoorbeeld een binding in twee richtingen in de LoginView sets de UserName of Password eigenschap instelt, wordt de validatie geactiveerd. In het volgende codevoorbeeld ziet u hoe dit gebeurt:

<Entry Text="{Binding UserName.Value, Mode=TwoWay}">
    <Entry.Behaviors>
        <behaviors:EventToCommandBehavior
            EventName="TextChanged"
            Command="{Binding ValidateUserNameCommand}" />
    </Entry.Behaviors>
</Entry>

Het Entry besturingselement wordt gekoppeld aan de UserName.Value eigenschap van het ValidatableObject<T> exemplaar en de verzameling van Behaviors het besturingselement heeft er een EventToCommandBehavior exemplaar aan toegevoegd. Dit gedrag wordt uitgevoerd ValidateUserNameCommand als reactie op de gebeurtenis die op de TextChanged Entrygebeurtenis wordt geactiveerd, die wordt gegenereerd wanneer de tekst in de Entry wijzigingen wordt weergegeven. Op zijn beurt voert de ValidateUserNameCommand gedelegeerde de ValidateUserName methode uit, waarmee de Validate methode op het ValidatableObject<T> exemplaar wordt uitgevoerd. Daarom wordt elke keer dat de gebruiker een teken invoert in het Entry besturingselement voor de gebruikersnaam, validatie van de ingevoerde gegevens uitgevoerd.

Validatiefouten weergeven

De eShop-app met meerdere platforms informeert de gebruiker over validatiefouten door het besturingselement met de ongeldige gegevens met een rode achtergrond te markeren en door een foutbericht weer te geven dat de gebruiker informeert waarom de gegevens ongeldig zijn onder het besturingselement met de ongeldige gegevens. Wanneer de ongeldige gegevens worden gecorrigeerd, verandert de achtergrond weer in de standaardstatus en wordt het foutbericht verwijderd. In de onderstaande afbeelding ziet u de LoginView app in de eShop-app met meerdere platforms wanneer er validatiefouten aanwezig zijn.

Validatiefouten weergeven tijdens de aanmelding.

Een besturingselement markeren dat ongeldige gegevens bevat

.NET MAUI biedt een aantal manieren om validatiegegevens aan eindgebruikers te presenteren, maar een van de meest eenvoudige manieren is door gebruik te maken van Triggers. Triggers bieden ons een manier om de status van onze besturingselementen te wijzigen, meestal voor uiterlijk, op basis van een gebeurtenis of gegevenswijziging die plaatsvindt voor een besturingselement. Voor validatie gebruiken we een DataTrigger die luistert naar wijzigingen die zijn gegenereerd vanuit een afhankelijke eigenschap en reageren op de wijzigingen. De Entry besturingselementen op de installatie LoginView worden ingesteld met behulp van de volgende code:

<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>

Hiermee DataTrigger geeft u de volgende eigenschappen op:

Eigenschappen Beschrijving
TargetType Het type besturingselement waartoe de trigger behoort.
Binding De gegevensmarkeringen Binding die wijzigingsmeldingen en waarde voor de triggervoorwaarde bieden.
Value De gegevenswaarde die moet worden opgegeven wanneer aan de voorwaarde van de trigger is voldaan.

EntryHiervoor luisteren we naar wijzigingen in de LoginViewModel.UserName.IsValid eigenschap. Telkens wanneer deze eigenschap een wijziging aanbrengt, wordt de waarde vergeleken met de Value eigenschap die in de DataTriggereigenschap is ingesteld. Als de waarden gelijk zijn, wordt aan de triggervoorwaarde voldaan en worden alle Setter objecten die aan de DataTrigger trigger worden verstrekt, uitgevoerd. Dit besturingselement heeft één Setter object waarmee de BackgroundColor eigenschap wordt bijgewerkt naar een aangepaste kleur die is gedefinieerd met behulp van de StaticResource markeringen. Wanneer niet meer aan een Trigger voorwaarde wordt voldaan, worden de eigenschappen die door het object zijn ingesteld, teruggezet naar de vorige status van het Setter besturingselement. Zie .NET MAUI Docs: Triggers voor meer informatie.Triggers

Foutberichten weergeven

In de gebruikersinterface worden validatiefouten weergegeven in labelbesturingselementen onder elk besturingselement waarvan de validatie van de gegevens is mislukt. In het volgende codevoorbeeld ziet u het Label foutbericht dat een validatiefout wordt weergegeven als de gebruiker geen geldige gebruikersnaam heeft ingevoerd:

<Label
    Text="{Binding UserName.Errors, Converter={StaticResource FirstValidationErrorConverter}"
    Style="{StaticResource ValidationErrorLabelStyle}" />

Elk label wordt gekoppeld aan de Errors eigenschap van het weergavemodelobject dat wordt gevalideerd. De Errors eigenschap wordt geleverd door de ValidatableObject<T> klasse en is van het type IEnumerable<string>. Omdat de Errors eigenschap meerdere validatiefouten kan bevatten, wordt het FirstValidationErrorConverter exemplaar gebruikt om de eerste fout op te halen uit de verzameling voor weergave.

Samenvatting

De eShop-app voor meerdere platforms voert synchrone clientvalidatie uit van weergavemodeleigenschappen en informeert de gebruiker over validatiefouten door het besturingselement met de ongeldige gegevens te markeren en door foutberichten weer te geven die de gebruiker informeren waarom de gegevens ongeldig zijn.

Modeleigenschappen weergeven waarvoor validatie is vereist, zijn van het type ValidatableObject<T>en voor elk ValidatableObject<T> exemplaar zijn validatieregels toegevoegd aan de Validations eigenschap. Validatie wordt aangeroepen vanuit het weergavemodel door de Validate methode van het ValidatableObject<T> exemplaar aan te roepen, waarmee de validatieregels worden opgehaald en uitgevoerd op basis van de ValidatableObject<T> eigenschap Waarde. Validatiefouten worden in de Errors eigenschap van het ValidatableObject<T> exemplaar geplaatst en de eigenschap IsValid van het ValidatableObject<T> exemplaar wordt bijgewerkt om aan te geven of de validatie is geslaagd of mislukt.