/// <summary> /// Проверяет свойства указанного объекта на основе их атрибутов. Свойства, не /// помеченные одним из валидационных атрибутов, пропускаются. /// </summary> /// /// <remarks> /// Все валидационные ошибки записываются в экземпляр <see cref="ValidationContext"/>, /// указанный при создании экземпляра данного класса. /// /// Если валидируемый объект имеет значение <c>null</c>, то валидация завершается /// успешно. Используйте <see cref="RequiredValidator"/>, /// если хотите проверить, имеет ли объект значение. /// /// В качестве ключей ошибок выступают имея свойства объекта, если к нему не /// применен атрибут <see cref="FlatErrorKeysAttribute"/>. /// </remarks> /// /// <param name="obj">Валидируемый объект.</param> /// <param name="context">Валидационный контекст.</param> public void Validate(IValidationContext context, object obj) { if (obj == null) { return; } var properties = obj.GetType().GetProperties(); foreach (var propertyInfo in properties) { var constraintAttributes = propertyInfo .GetCustomAttributes(typeof(ValidateAttribute), true) .Union(propertyInfo.GetCustomAttributes(typeof(ValidationAttribute), true)) .ToArray(); if (!constraintAttributes.Any()) { continue; } var flatKeys = propertyInfo .GetCustomAttributes(typeof(FlatErrorKeysAttribute), true) .Any(); var value = propertyInfo.GetValue(obj, null); if (flatKeys) { ValidationAction(context, value, constraintAttributes); } else { using (context.PrefixErrorKeysWithName(propertyInfo.Name)) { ValidationAction(context, value, constraintAttributes); } } } }