Проверка
Совет
Это содержимое является фрагментом из электронной книги, шаблонов корпоративных приложений с помощью .NET MAUI, доступных в .NET Docs или в виде бесплатного скачиваемого PDF-файла, который можно прочитать в автономном режиме.
Любое приложение, которое принимает входные данные от пользователей, должно убедиться, что входные данные допустимы. Например, приложение может проверить входные данные, содержащие только символы в определенном диапазоне, определенную длину или соответствующий определенному формату. Без проверки пользователь может предоставить данные, которые приводят к сбою приложения. Правильная проверка применяет бизнес-правила и может помочь предотвратить внедрение злоумышленником вредоносных данных.
В контексте шаблона Model-View-ViewModel (MVVM) модель представления или модель часто требуется для выполнения проверки данных и сигнала о любых ошибках проверки в представлении, чтобы пользователь смог исправить их. Приложение с несколькими платформами 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 экземпляра обновляется, чтобы указать, выполнена ли проверка успешно или не выполнена.