Проверка формы MVC на нескольких полях - PullRequest
20 голосов
/ 20 мая 2011

Как бы я хотел, чтобы несколько текстовых полей в форме MVC 3 рассматривались как одно для целей проверки?

Это простое поле номера телефона с одним текстовым полем для кода города, одним для префикса и одним дляпоследние четыре цифры.

На самом деле есть два требования проверки:

1) Все они обязательны.2) Все они должны содержать целые числа.

Теперь это просто, когда вы делаете это для отдельных полей, но как я могу создать эквивалент ASP.NET CustomValidator с MVC, чтобы я мог проверить все три поля в целом

Ответы [ 3 ]

21 голосов
/ 24 мая 2011

Я фактически закончил реализацию пользовательского ValidationAttribute, чтобы решить эту проблему, используя тот же тип логики, представленный в CompareAttribute, который позволяет вам использовать отражение для оценки значений других свойств.Это позволило мне реализовать это на уровне свойств вместо уровня модели, а также разрешить проверку на стороне клиента с помощью ненавязчивого JavaScript:

public class MultiFieldRequiredAttribute : ValidationAttribute, IClientValidatable
    {
        private readonly string[] _fields;

        public MultiFieldRequiredAttribute(string[] fields)
        {
            _fields = fields;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            foreach (string field in _fields)
            {
                PropertyInfo property = validationContext.ObjectType.GetProperty(field);
                if (property == null)
                    return new ValidationResult(string.Format("Property '{0}' is undefined.", field));

                var fieldValue = property.GetValue(validationContext.ObjectInstance, null);

                if (fieldValue == null || String.IsNullOrEmpty(fieldValue.ToString()))
                    return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }

            return null;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule
            {
                ErrorMessage = this.ErrorMessage,
                ValidationType = "multifield"
            };
        }
    }
17 голосов
/ 20 мая 2011

Вы можете справиться с этим, поместив IValidatableObject в класс модели и реализовав метод Validate.

Это может выглядеть примерно так:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
      if (String.IsNullOrEmpty(_PhonePart1) || String.IsNullOrEmpty(_PhonePart2)
            || String.IsNullOrEmpty(_PhonePart3))
      {
           yield return new ValidationResult("You must enter all " + 
                  "three parts of the number.");
      }

}
1 голос
/ 21 мая 2011

Скотт, Используете ли вы пользовательскую модель связующего в вашей области?Если это так, вы можете реализовать IModelBinder, чтобы объединить результаты из трех текстовых полей в одно поле телефонного номера, которое может быть украшено атрибутами проверки.Вот вопрос о стеке потока, который имеет пример того, как это сделать: Проверки аннотаций и пользовательский ModelBinder

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...