0

我有以下用于自定义验证的类:

[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public sealed class RequiredIfAnyTrueAttribute : ValidationAttribute, IClientValidatable
{
    private const string DefaultErrorMessage = "{0} is required";

    public List<string> OtherProperties { get; private set; }

    public RequiredIfAnyTrueAttribute(string otherProperties)
        : base(DefaultErrorMessage)
    {
        if (string.IsNullOrEmpty(otherProperties))
            throw new ArgumentNullException("otherProperty");

        OtherProperties = new List<string>(otherProperties.Split(new char[] { '|', ',' }));
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name);
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null)
        {
            foreach (string s in OtherProperties)
            {
                var otherProperty = validationContext.ObjectType.GetProperty(s);
                var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);

                if (otherPropertyValue.Equals(true))
                    return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
        }

        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var clientValidationRule = new ModelClientValidationRule()
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "requiredifanytrue"
        };

        clientValidationRule.ValidationParameters.Add("otherproperties", string.Join("|",OtherProperties));

        return new[] { clientValidationRule };
    }
}

我的视图模型是:

public class SampleViewModel
{
    public bool PropABC { get; set; }
    public bool PropXYZ { get; set; }

    [RequiredIfAnyTrue("PropABC|PropXYZ")]
    public int? TestField { get; set; }
}

当我的强类型视图呈现时,一切看起来都正常。如果选择了 PropABC 或 PropXYZ,那么我需要为 TestField 输入一个值。客户端和服务器端验证都是有效的。

但是,鉴于以下事件顺序:

  1. 检查 PropABC
  2. 提交表格
  3. 需要 TestField 的客户端验证触发
  4. 取消选中 PropABC
  5. 客户端验证不会重新触发,并且验证消息会一直保留到表单提交

为了解决#5,我通常会通过 jquery onread 将点击事件附加到复选框以重新启动验证。

在给定 MVC3 + unobtrusive + jquery 的情况下,是否有首选/推荐的手动强制客户端验证方式?

4

3 回答 3

1

您需要编写自己的属性吗?如果不是,我认为您可以避免“重新发明轮子”

FoolProof效果很好。你得到它作为一个 NuGet 包。

NuGet: install-package foolproof

它包括许多用于即时必填字段等的各种组合的重要属性。

于 2011-08-25T18:38:55.603 回答
1

肖恩,附加到事件是获得验证重新启动的最佳方法。

我建议创建一个名为“validate”的类(或类似的东西),将其添加到要验证的每个元素中,然后使用 jQuery 附加到每个元素的单击和模糊事件(可能还有更改事件)该类,并像这样验证元素:

$("form").validate().element(this);
于 2011-08-28T13:57:43.287 回答
0

FoolProof 仍处于测试阶段,不适用于嵌套视图模型,也不适用于数组

于 2013-11-06T13:45:44.687 回答