Содержание
В предыдущей части мы рассмотрели атрибуты валидации, которые нам предоставляются платформой .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. В зависимости от наших потребностей мы можем создавать как атрибуты для проверки отдельных свойств модели, так и модели (объекта) целиком.