Валидация модели, то есть её проверка на допустимость значений, содержащихся в ней – это, строго говоря, механизм самой платформы .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.