多字段的 MVC 表单验证

Posted

技术标签:

【中文标题】多字段的 MVC 表单验证【英文标题】:MVC Form Validation on Multiple Fields 【发布时间】:2011-08-29 20:10:37 【问题描述】:

我将如何将 MVC 3 表单上的多个文本框视为一个以进行验证?

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

实际上有两个验证要求:

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

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

【问题讨论】:

我的评论没有解决您的验证问题,但我想知道这是否是用于输入电话号码的最佳 UI。这种设计对用户来说不是更多的工作吗?文本框之间的制表符,如果他们想粘贴电话号码或删除已经输入的电话号码,则需要更多工作。我原以为带有基于正则表达式的验证的单个文本框会更常见。 如果我在做决定,我会说你是对的,但出于某种原因,有人决定它需要三个文本框。不要问。 :) 哎哟。你能用我引用的例子来改变他们的意见吗?另外,我假设您不需要任何非美国人将他们的电话号码输入此系统......因为我们的电话号码通常格式不同。 【参考方案1】:

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

【讨论】:

我必须将 ValidationType 更改为“必需”才能进行客户端验证工作。我发现这个答案 (***.com/questions/13740489/…) 对 ValidationType 接受的值很有帮助。【参考方案2】:

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


【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于多字段的 MVC 表单验证的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MVC 4 中使用 jquery 验证表单的隐藏输入字段?

让 MVC 4 验证 jquery 手风琴表单的所有部分

使用休眠验证器的 Spring mvc 表单验证

在 asp.net mvc razor 页面中验证 jquery 中的特定表单字段

多个选项卡中的 MVC 表单验证 - 自动跳转到有验证错误的选项卡?

预提交必填字段验证 ASP .NET MVC