Поделиться через


Проверка

Совет

Это содержимое является фрагментом из электронной книги, шаблонов корпоративных приложений с помощью .NET MAUI, доступных в .NET Docs или в виде бесплатного скачиваемого PDF-файла, который можно прочитать в автономном режиме.

Корпоративные шаблоны приложений с помощью эскиза обложки электронной книги .NET MAUI .

Любое приложение, которое принимает входные данные от пользователей, должно убедиться, что входные данные допустимы. Например, приложение может проверить входные данные, содержащие только символы в определенном диапазоне, определенную длину или соответствующий определенному формату. Без проверки пользователь может предоставить данные, которые приводят к сбою приложения. Правильная проверка применяет бизнес-правила и может помочь предотвратить внедрение злоумышленником вредоносных данных.

В контексте шаблона Model-View-ViewModel (MVVM) модель представления или модель часто требуется для выполнения проверки данных и сигнала о любых ошибках проверки в представлении, чтобы пользователь смог исправить их. Приложение с несколькими платформами eShop выполняет синхронную проверку свойств модели просмотра и уведомляет пользователя о любых ошибках проверки, выделите элемент управления, содержащий недопустимые данные, и отображая сообщения об ошибках, информирующие пользователя о том, почему данные недопустимы. На рисунке ниже показаны классы, участвующие в выполнении проверки в приложении с несколькими платформами eShop.

Классы проверки в мультиплатформенное приложение eShop.

Просмотр свойств модели, требующих проверки, имеет тип ValidatableObject<T>, и каждый ValidatableObject<T> экземпляр имеет правила проверки, добавленные в его Validations свойство. Проверка вызывается из модели представления путем вызова Validate метода экземпляра ValidatableObject<T> , который извлекает правила проверки и выполняет их для ValidatableObject<T>.Value свойства. Все ошибки проверки помещаются в Errors свойство экземпляра ValidatableObject<T> , а IsValid свойство ValidatableObject<T> экземпляра обновляется, чтобы указать, успешно ли выполнена проверка или сбой. В следующем коде показана 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;
    }
}

Уведомление об изменении свойств предоставляется классом ObservableObject , поэтому Entry элемент управления может привязаться к IsValid свойству экземпляра ValidatableObject<T> в классе модели представления, чтобы получать уведомление о том, является ли введенные данные допустимыми.

Указание правил проверки

Правила проверки задаются путем создания класса, наследуемого IValidationRule<T> от интерфейса, который показан в следующем примере кода:

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

Этот интерфейс указывает, что класс правил проверки должен предоставить логический Check метод, используемый для выполнения обязательной проверки, и ValidationMessage свойство, значение которого является сообщением об ошибке проверки, которое будет отображаться при сбое проверки.

В следующем примере кода показано IsNotNullOrEmptyRule<T> правило проверки, которое используется для проверки имени пользователя и пароля, введенных пользователем LoginView при использовании макетных служб в мультиплатформенное приложение eShop:

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

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

Метод Check возвращает логическое значение, указывающее, является ли аргумент значения null, пустым или состоит только из символов пробелов.

Хотя приложение eShop не использует многоплатформенное приложение, в следующем примере кода показано правило проверки для проверки адресов электронной почты:

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

Метод Check возвращает логическое значение, указывающее, является ли аргумент значения допустимым адресом электронной почты. Это достигается путем поиска аргумента значения для первого вхождения шаблона регулярного выражения, указанного в конструкторе Regex . Можно ли определить шаблон регулярного выражения в входной строке, проверив егоvalue.Regex.IsMatch

Примечание.

Проверка свойств иногда может включать зависимые свойства. Пример зависимых свойств заключается в том, что набор допустимых значений для свойства A зависит от конкретного значения, заданного в свойстве B. Чтобы проверить, является ли значение свойства A одним из допустимых значений, потребуется получить значение свойства B. Кроме того, при изменении значения свойства B необходимо будет пересмотреть свойство A.

Добавление правил проверки в свойство

В приложении с несколькими платформами eShop свойства модели просмотра, требующие проверки, объявляются типом ValidatableObject<T>, где T является тип проверяемых данных. В следующем примере кода показан пример двух таких свойств:

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

Для выполнения проверки правила проверки необходимо добавить в коллекцию "Проверки" каждого ValidatableObject<T> экземпляра, как показано в следующем примере кода:

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

Этот метод добавляет IsNotNullOrEmptyRule<T> правило проверки в коллекцию каждого ValidatableObject<T> экземпляра, указывая значения свойства правила Validations ValidationMessage проверки, которое указывает сообщение об ошибке проверки, которое будет отображаться при сбое проверки.

Активация проверки

Подход проверки, используемый в мультиплатформенных приложениях eShop, может вручную активировать проверку свойства и автоматически активировать проверку при изменении свойства.

Активация проверки вручную

Проверку можно активировать вручную для свойства модели представления. Например, это происходит в мультиплатформенных приложениях eShop, когда пользователь нажимает Login кнопку на вкладке LoginView, при использовании макетных служб. Делегат команды вызывает MockSignInAsync метод в LoginViewModelметоде, который вызывает проверку путем выполнения Validate метода, который показан в следующем примере кода:

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

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

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

Метод Validate выполняет проверку имени пользователя и пароля, введенных пользователем, LoginViewпутем вызова Validate метода на каждом ValidatableObject<T> экземпляре. В следующем примере кода показан Validate метод из 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;
}

Этот метод извлекает все правила проверки, добавленные в коллекцию объекта Validations . Метод Check для каждого полученного правила проверки выполняется, а ValidationMessage значение свойства для любого правила проверки, которое не может проверить данные, добавляется в Errors коллекцию экземпляра ValidatableObject<T> . Наконец, свойство задано, и его значение возвращается вызывающему методу, указывая, IsValid выполнена ли проверка успешно или завершилась ошибкой.

Активация проверки при изменении свойств

Проверка также активируется автоматически при изменении привязанного свойства. Например, когда двусторонняя привязка в наборах LoginView UserName или Password свойстве активируется. В следующем примере кода показано, как это происходит:

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

Элемент Entry управления привязывается к UserName.Value свойству ValidatableObject<T> экземпляра, а в коллекцию EventToCommandBehavior элемента управления Behaviors добавлен экземпляр. Это поведение выполняется в ответ на TextChanged событие, которое Entryвозникает ValidateUserNameCommand при изменении текстаEntry. В свою очередь делегат ValidateUserNameCommand выполняет ValidateUserName метод, который выполняет Validate метод на экземпляре ValidatableObject<T> . Таким образом, каждый раз, когда пользователь вводит символ в Entry элементе управления для имени пользователя, выполняется проверка введенных данных.

Отображение ошибок проверки

Приложение eShop с несколькими платформами уведомляет пользователя о любых ошибках проверки, выделите элемент управления, содержащий недопустимые данные с красным фоном, и отображая сообщение об ошибке, информирующее пользователя о том, почему данные недопустимы под элементом управления, содержащим недопустимые данные. При исправлении недопустимых данных фон изменяется обратно в состояние по умолчанию и удаляется сообщение об ошибке. На рисунке ниже показано LoginView в приложении с несколькими платформами eShop при наличии ошибок проверки.

Отображение ошибок проверки во время входа.

Выделение элемента управления, содержащего недопустимые данные

.NET MAUI предлагает несколько способов представления сведений о проверке конечным пользователям, но одним из наиболее прямых способов является использование Triggers. Triggers предоставьте нам способ изменить состояние наших элементов управления, как правило, для внешнего вида на основе события или изменения данных, возникающих для элемента управления. Для проверки мы будем использовать объект DataTrigger , который будет прослушивать изменения, возникающие из связанного свойства, и реагировать на изменения. Элементы Entry управления для этого LoginView настраиваются с помощью следующего кода:

<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 следующие свойства:

Свойство Description
TargetType Тип элемента управления, к которому принадлежит триггер.
Binding Разметка данных Binding , которая будет предоставлять уведомления об изменениях и значение для условия триггера.
Value Значение данных, указывающее, когда выполняется условие триггера.

Для этого Entryмы будем прослушивать изменения в свойстве LoginViewModel.UserName.IsValid . Каждый раз, когда это свойство вызывает изменение, значение будет сравниваться со свойством Value , заданным в параметре DataTrigger. Если значения равны, условие триггера будет выполнено и все Setter объекты, предоставленные DataTrigger для этого объекта. Этот элемент управления содержит один Setter объект, который обновляет BackgroundColor свойство на настраиваемый цвет, определенный с помощью разметки StaticResource . Trigger Если условие больше не выполнено, элемент управления отвернет свойства, заданные Setter объектом в предыдущее состояние. Дополнительные сведения см. в документации по .NETMAUI: триггеры.Triggers

Отображение сообщений об ошибках

В пользовательском интерфейсе отображаются сообщения об ошибках проверки в элементах управления Label под каждым элементом управления, данные которого не прошли проверку. В следующем примере кода показано Label сообщение об ошибке проверки, если пользователь не ввел допустимое имя пользователя:

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

Каждая метка привязывается к Errors свойству проверяемого объекта модели представления. Свойство Errors предоставляется классом ValidatableObject<T> и имеет тип IEnumerable<string>. Errors Так как свойство может содержать несколько ошибок проверки, FirstValidationErrorConverter экземпляр используется для получения первой ошибки из коллекции для отображения.

Итоги

Приложение eShop с несколькими платформами выполняет синхронную проверку свойств модели просмотра и уведомляет пользователя о любых ошибках проверки, выделите элемент управления, содержащий недопустимые данные, и отображая сообщения об ошибках, информирующие пользователя о том, почему данные недопустимы.

Просмотр свойств модели, требующих проверки, имеет тип ValidatableObject<T>, и каждый ValidatableObject<T> экземпляр имеет правила проверки, добавленные в его Validations свойство. Проверка вызывается из модели представления путем вызова Validate метода ValidatableObject<T> экземпляра, который извлекает правила проверки и выполняет их в свойстве ValidatableObject<T> Value. Все ошибки проверки помещаются в Errors свойство экземпляра ValidatableObject<T> , а свойство ValidatableObject<T> IsValid экземпляра обновляется, чтобы указать, выполнена ли проверка успешно или не выполнена.