Содержание
В предыдущей части мы рассмотрели атрибуты валидации, которые нам предоставляются платформой .NET для проверки моделей. Однако, валидация модели в C# не ограничивается только этими атрибутами — нам может потребоваться более сложная проверка для которой готовых атрибутов валидации может не хватить. В этом случае мы можем создать собственный атрибут валидации и использовать его в своем приложении.
Создание атрибута валидации свойства модели
В предыдущей части мы рассматривали такой атрибут валидации модели как Range
, который позволяет проверить вхождение числа в заданный диапазон. Напишем свой собственный атрибут, который будет проверять вхождение заданного числа не в один, а два диапазона.
class RangeExtAttribute : ValidationAttribute { public int MinimumFirst { get; set; } public int MaximumFirst { get; set; } public int MinimumLast { get; set; } public int MaximumLast { get; set; } public RangeExtAttribute(int minimumFirst, int maximumFirst, int minimumLast, int maximumLast) { MinimumFirst = minimumFirst; MaximumFirst = maximumFirst; MinimumLast = minimumLast; MaximumLast = maximumLast; } public override bool IsValid(object? value) { if (value == null) { ErrorMessage = "Значение свойства не должно быть равным null"; return false; } if (value.GetType() != typeof(int)) { ErrorMessage = "Cвойства должно должно иметь тип int"; return false; } int intValue = (int)value; if ((intValue < MinimumFirst) || (intValue > MaximumLast) || ((intValue > MaximumFirst) && (intValue < MinimumLast))) { ErrorMessage = $"Значение свойства должно лежать в диапазоне [{MinimumFirst},{MaximumFirst}] или в диапазоне [{MinimumLast},{MaximumLast}]"; return false; } return true; } }
Для создания собственного атрибута валидации мы создали класс-наследник от ValidationAttribete
и переопределили в нем метод IsValid
. Этот метод должен возвращать true
, если свойство прошло валидацию и false
— в ином случае. Так как мы проверяем только значения int
, то вначале производится проверка проверяемого значения на null
и тип данных. Далее — мы проверяем число на вхождение в один из заданных диапазонов и, если проверка прошла успешно, то возвращаем значение true
.
Воспользоваться этим атрибутом также просто, как и уже имеющимися атрибутами валидации из пространства имен System.ComponentModel.DataAnnotations
class Model { [RangeExt(0,5,7,10)] public int Value { get; set; } }
Обратите внимание, что мы можем опустить в имени класса атрибута часть «Attribute
«. Проверим работу атрибута:
Значение свойства должно лежать в диапазоне [0,5] или в диапазоне
[7,10]
Создание атрибута валидации для модели в целом
Атрибуты валидации, применяемые сразу ко всей модели, чаще всего, используются для проверки нескольких свойств. В целом же, создание такого атрибута ни чем не сложнее, чем в предыдущем примере. Например,
public class AllRequiredAttribute: ValidationAttribute { public override bool IsValid(object? value) { Model model = value as Model; if (model.Value == 0) { ErrorMessage = "Значение Value не может быть равно нулю"; return false; } if (model.Name == null) { ErrorMessage = "Значение Name не может быть равно null"; return false; } return true; } }
здесь мы производим проверку модели у которой значение Value
не должно быть равным нулю, а свойство Name
не должно быть равно null
. Проверим работу атрибута следующим образом:
[AllRequired] class Model { [RangeExt(0,5,7,10)] public int Value { get; set; } public string? Name { get; set; } = null; }
Результат работы программы:
Значение Name не может быть равно null
Итого
Собственные атрибуты валидации должны являться наследниками класса ValidationAttribute
и переопределять метод IsValid
. В зависимости от наших потребностей мы можем создавать как атрибуты для проверки отдельных свойств модели, так и модели (объекта) целиком.