多字段的MVC表单验证

时间:2011-05-20 17:06:30

标签: c# asp.net-mvc validation forms asp.net-mvc-3

如何将MVC 3表单上的多个文本框视为一个用于验证的文本框?

这是一个简单的电话号码字段,其中一个区域代码文本框,一个用于前缀,一个用于最后四位数字。

确实有两个验证要求:

1)他们都是必需的。 2)它们都必须包含整数。

现在对单个字段执行此操作很简单但是如何使用MVC创建ASP.NET CustomValidator的等效项,以便我可以将所有三个字段作为一个整体进行验证?

3 个答案:

答案 0 :(得分:21)

我实际上最终实现了一个自定义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"
            };
        }
    }

答案 1 :(得分:17)

您可以通过将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.");
      }

}

答案 2 :(得分:1)

Scott,您的范围内是否使用自定义模型绑定器?如果是这样,您可以实现IModelBinder将三个文本字段的结果合并到一个电话号码字段中,该字段可以使用验证属性进行修饰。这是一个stackoverflow问题,其中有一个如何执行此操作的示例:DataAnnotation Validations and Custom ModelBinder