Валидация модели. Атрибуты валидации

Валидация модели, то есть её проверка на допустимость значений, содержащихся в ней – это, строго говоря, механизм самой платформы .NET. Однако, в ASP.NET Core этот механизм расширен и дополнен. Поэтому, не лишним будет затронуть и вопросы связанные с валидацией модели в этой части.

Если какое-либо свойство объекта, представляющее собой обычный тип, не передается в запросе, то ему присваивается значение по умолчанию. Например, свойствам, представляющим собой целые числа по умолчанию, присваивается 0. Если мы допускаем необязательность наличия какого-либо параметра в запросе, то мы определяем параметр метода как допускающий null. Однако, при работе с ресурсами API такого поведения может быть недостаточно и, более того, такое поведение может отразиться на корректности данных и, в принципе, работоспособности нашего приложения.

Атрибуты валидации

Атрибуты валидации модели позволяют подключать к проверке тех или иных свойств дополнительную логику. Например, мы можем проверять строковые значения на соответствие регулярному выражению или проверять вхождение числа в заданный диапазон значений и т. д. Можно выделить следующие основные атрибуты, используемые для валидации модели:

  • Required
  • StringLength
  • Range
  • RegularExpression
  • Compare

Все эти атрибуты относятся к механизму валидации непосредственно платформы .NET и содержатся в пространстве имен System.ComponentModel.DataAnnotations. Вкратце рассмотрим эти атрибуты и их действие при валидации модели.

Класс ValidationAttribute

Абстрактный класс ValidationAttribute является родительским классом для всех атрибутов валидации и определяет следующие свойства, которые мы можем использовать для валидации модели

Имя Тип Описание
ErrorMessage string Сообщение об ошибке валидации
ErrorMessageResourceName string Эти свойства используются в случае, если вам необходимо получить локализованное значение строки с ошибкой из ресурсов приложения.
ErrorMessageResourceType Type
ErrorMessageString String
RequiresValidationContext bool Значение, указывающее, требуется ли для атрибута контекст проверки.

При необходимости мы можем унаследовать свой собственный класс атрибута валидации от ValidationAttribute. Теперь рассмотрим основные классы валидации модели, которые мы можем использовать в приложении ASP.NET Core Web API.

Атрибут Required

Этот атрибут означает, что свойство, к которому он применен обязательно должно иметь какое-либо значение. У этого атрибута определены следующие свойства

Имя Тип Описание
AllowEmptyStrings bool Указывает, допускается ли использование пустых строк в свойстве

Атрибут StringLength

Атрибут StringLength используется для указания минимальной и максимальной длины строки, разрешенной в поле данных, и определяет следующие свойства

Имя Тип Описание
MaximumLength int Максимальная длина строки (обязательно должно указываться в атрибуте)
MinimumLength int Минимальная длина строки

Атрибут Range

Этот атрибут определяет диапазон значений, которые может принимать свойство или поле модели и содержит свойства

Имя Тип Описание
ConvertValueInInvariantCulture bool Определяет, использовать ли при преобразовании типа, указанного в свойстве OperandType значение CultureInfo.InvariantCulture. Значение этого свойства не влияет на конвертацию Int32 и Double
Maximum object Максимальное значение в диапазоне
MaximumIsExclusive bool Указывает, должна ли завершиться ошибкой проверка для значений, равных значению, указанному в свойстве Maximum.
Minimum object Минимальное значение в диапазоне
MinimumIsExclusive Bool Указывает, должна ли завершиться ошибкой проверка для значений, равных значению, указанному в свойстве Minimum.
OperandType Type Тип значения, которое должно валидироваться
ParseLimitsInInvariantCulture Bool Определяет, использовать ли значение CultureInfo.InvariantCulture при преобразовании значений, указанных в свойствах Minimum и Maximum

Как видно из свойств этого атрибута, [Range], в отличие от атрибута [StringLength] позволяет работать с любыми значениями, которые реализуют интерфейс IComparable.

Атрибут RegularExpression

Этот атрибут проверяет соответствие значения поля или свойства регулярному выражению. Атрибут предоставляет следующие свойства

Имя Тип Описание
MatchTimeout TimeSpan Возвращает время ожидания выполнения всех операций сравнения. Свойство только для чтения.
MatchTimeoutInMilliseconds int Задает время в миллисекундах для выполнения одной операции сопоставления значения свойства с шаблоном, заданным в свойстве Pattern (по умолчанию 2000 мс)
Pattern string Регулярное выражение

Этот атрибут удобно применять, когда строковое значение свойства может принимать различные значения, но, при этом, значения должны соответствовать определённому шаблону. Ниже представлен пример использования атрибута [RegularExpression] для проверки того, что свойство содержит адрес email

[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}"]

public string? Email { get; set; }

Соответственно, если свойство не пройдет валидацию, то сервер ответит ошибкой и сообщит, что свойство не соответствует заданному шаблону (если, конечно, вы не зададите самостоятельно свойство ErrorMessage).

Атрибут Compare

Атрибут [Compare] позволяет сравнивать два свойства объекта и предоставляет следующие свойства

Имя Тип Описание
OtherProperty string Имя свойства для сравнения

Например, этот атрибут удобно использовать для сравнения паролей, которые вводит пользователь

public string Password { get; set; }

[Compare("Password")]
public string ConfirmPassword { get; set; }

Атрибуты валидации, доступные в .NET 8 и более поздних версиях

В .NET 8, были добавлены новые атрибуты валидации, рассмотрим их.

Атрибут AllowedValues

Атрибут [AllowedValues] позволяет ограничить перечень допустимых значений этого свойства. Например, ниже показано применение этого атрибута для свойства модели

public class TaskData
      {

            public int Id { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public DateTime CreatedDate { get; set; } = DateTime.Now;
            public DateTime Deadline { get; set; }

            [AllowedValues([TaskStatus.Active,
                  TaskStatus.Completed,
                  TaskStatus.Expired],
                  ErrorMessage ="Свойство Status содержит недопустимое значение")]

            public TaskStatus Status { get; set; }
      }

Теперь пользователь сможет добавить в базу данных задачу, содержащую только один из трех статусов – Active, Completed или Expired. Попытка добавить задачу с другим статусом приведет к ошибке валидации.

Атрибут DeniedValues

Действие этого атрибута прямо противоположное атрибуту [AllowedValues] – он определяет перечень запрещенных значений свойства. Применение его также аналогично предыдущему атрибуту.

Атрибут Base64String

Этот атрибут определяет, что значение поля данных представляет собой правильно сформированную строку Base64. Работа этого атрибута завязана на использовании класса Convert, а именно – на его методе TryFromBase64String(). Если метод возвращает значение false, то генерируется ошибка валидации модели.

Применение атрибутов валидации в приложениях ASP.NET Core Web API

В качестве примера будет использовано приложение из предыдущей части. Валидация модели активно используется в приложениях ASP.NET Core Web API при выполнении POST- и PUT-запросов (на добавление и обновление ресурсов). В нашем шаблонном приложении ASP.NET Core такого действия контроллера не предусмотрено — создадим его (оно нам пригодится и в следующей части). Добавим в контроллер WeatherForecastController действие на добавление нового ресурса:

List<WeatherForecast> forecasts = new();

[HttpPost]
public ActionResult Add(WeatherForecast forecast) 
{
    forecasts.Add(forecast);
    return Ok();
}

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

Теперь добавим атрибуты валидации к классу WeatherForecast:

public enum ForecastSummary {Freezing, Bracing, Chilly, Cool, Mild, Warm, Balmy, Hot, Sweltering, Scorching };


public class WeatherForecast
{
    public int Id { get; set; }
    public DateOnly Date { get; set; }

    [Range(minimum: -20, maximum: 55, ErrorMessage = "Значение температуры выходят за пределы допустимых значений [-20, 55]")]
    public int TemperatureC { get; set; }

    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

    [AllowedValues([ForecastSummary.Chilly, ForecastSummary.Cool])]
    public ForecastSummary Summary { get; set; }
}

Здесь мы ограничили значение температуры диапазоном от -20 до 55 градусов, а для свойства Summary указали допустимые значения — Chilly и Cool. Теперь для тестирования, добавим в http-файл следующий запрос:

@temperature = 45
@summary = "Chilly"

POST {{WebApplication5_HostAddress}}/weatherforecast
Content-Type: application/json

{
   "date": "2025-03-16",
   "temperatureC": {{temperature}},
   "temperatureF": 112,
   "summary": {{summary}}

Этот запрос не вызовет ошибок валидации и, если его выполнить, то мы получим следующий результат:

Теперь изменим значение переменной temperature в запросе так, чтобы оно выходило за пределы допустимых значений, например,

@temperature = 100

и снова попытаемся выполнить запрос:

Как видите, произошла ошибка валидации модели. Этот пример, кстати, наглядно демонстрирует действие атрибута [ApiController] для класса контроллера. Это и есть автоматический отклик HTTP 400. Аналогичное сообщение мы получим и в том случае, если обе переменные в запросе будут иметь недопустимые значения:

Итого

Мы рассмотрели основные моменты валидации модели в ASP.NET Core Web API с использованием атрибутов валидации. На этом тема валидации модели в ASP.NET Core не заканчивается и в следующей части мы рассмотрим вопросы валидации модели, касающиеся непосредственно ASP.NET Core Web API.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии