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

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

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

实际上有两个验证要求:

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

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

【问题讨论】:

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

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


【解决方案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"
            };
        }
    }

【讨论】:

【解决方案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 以将三个文本字段的结果组合到一个电话号码字段中,该字段可以使用验证属性进行修饰。这是一个 stackoverflow 问题,其中包含如何执行此操作的示例:DataAnnotation Validations and Custom ModelBinder

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      相关资源
      最近更新 更多