2

得到了一个具有数据注释验证器属性的模型。一个典型的例子是:

 [RegularExpression("^[a-z]{5,}$", ErrorMessage="required field, must have correct format")]
 public string SomeProperty {get;set; }

我需要使这些验证器有条件:如果模型中的特定属性具有特定值,则应禁用大多数验证器。- 在服务器端和客户端。((我正在使用标准 Ms Ajax 客户端验证)

没有使 Data Annotation Validators 有条件的默认方法,所以我四处寻找一些实现新型 Data annotation 验证器的库。查看了 Foolproof.codeplex.com 和 RequiredIf 验证属性。但是我发现我要么无法正确实现它们,要么它们的实现过于简单(foolProof 只允许您检查单个条件)

对我来说最好的解决方案是,如果我可以为验证器提供 2 个参数:一个条件表达式和一个验证器。可能看起来像这样:

 [RequiredIf("OtherProperty == true", RegularExpression=@"^[a-z]{5,}$", ErrorMessage="required field, must have correct format")]
 public string SomeProperty {get;set; }

您推荐的任何其他库,或我可以尝试的其他类型的解决方案?

4

4 回答 4

2

看起来您想从万无一失的使用RegularExpressionIf验证器。

于 2013-05-06T05:32:51.160 回答
0

您可以通过在模型中实现来使用自定义验证IValidatableObject并执行您需要执行的任何条件。

你需要实现Validate方法。

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

    if (condition)
        yield return new ValidationResult("Your error message", new string[] { "Info" });
}
于 2013-05-06T03:53:42.253 回答
0

是的,没有办法用属性有条件地进行内置验证。仅仅是因为属性不是可选的。

我建议您尝试:https ://fluentvalidation.codeplex.com/

在任何情况下,您都需要通过上下文(如 Scartag 提及)或使用此流利的 API 手动处理 ValidationResult。

于 2013-05-06T03:54:47.203 回答
0

我最近处理了一个类似的问题,我尝试了在网上找到的各种解决方案,但收效甚微。

最终我为此创建了一个新的自定义属性,这是我的实现,效果很好!

  • 创建一个新类:

    public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
    {
    
        private string DependentProperty { get; set; }
        private object DesiredValue { get; set; }
        private readonly RequiredAttribute _innerAttribute;
    
        public RequiredIfAttribute(string dependentProperty, object desiredValue)
        {
            DependentProperty = dependentProperty;
            DesiredValue = desiredValue;
            _innerAttribute = new RequiredAttribute();
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var dependentValue = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty).GetValue(validationContext.ObjectInstance, null);
    
            if (Regex.IsMatch(dependentValue.ToString(), DesiredValue.ToString()))
            {
                if (!_innerAttribute.IsValid(value))
                {
                    return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
                }
            }
            return ValidationResult.Success;
        }
    
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext controllerContext)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = ErrorMessageString,
                ValidationType = "requiredif",
            };
            rule.ValidationParameters["dependentproperty"] = GetPropertyId(metadata, controllerContext as ViewContext);
            rule.ValidationParameters["desiredvalue"] = DesiredValue is bool ? DesiredValue.ToString().ToLower() : DesiredValue;
    
            yield return rule;
        }
    
        private string GetPropertyId(ModelMetadata metadata, ViewContext viewContext)
        {
            string propertyId = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(DependentProperty);
            var parentField = metadata.PropertyName + "_";
            return propertyId.Replace(parentField, "");
        }
    }
    
  • 然后创建一个新的 javascript 文件:

    $.validator.unobtrusive.adapters.add('requiredif', ['dependentproperty', 'desiredvalue'], function (options) {
        options.rules['requiredif'] = options.params;
        options.messages['requiredif'] = options.message;
    });
    
    $.validator.addMethod('requiredif', function (value, element, parameters) {
        var desiredvalue = parameters.desiredvalue;
        desiredvalue = (desiredvalue == null ? '' : desiredvalue).toString();
        var controlType = $("input[id$='" + parameters.dependentproperty + "']").attr("type");
        var actualvalue = {}
        if (controlType == "checkbox" || controlType == "radio") {
            var control = $("input[id$='" + parameters.dependentproperty + "']:checked");
            actualvalue = control.val();
        } else {
            actualvalue = $("#" + parameters.dependentproperty).val();
        }
        if ($.trim(actualvalue).match($.trim(desiredvalue))) {
            var isValid = $.validator.methods.required.call(this, value, element, parameters);
            return isValid;
        }
        return true;
    });
    

显然,将您的这个 javascript 文件(在我的情况下为“custom-validation.js”)导入您的视图。

    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/custom-validation.js")"></script>
  • 然后,进行设置后,您可以像使用标准属性之一一样使用它:

    [RequiredIf("Country", @"^((?!USA).)*$", ErrorMessage = "Please specify a province if you're not from the United States.")]
    public string Province { get; set; }
    

希望这可以帮助其他人解决这个问题。

于 2016-07-29T12:56:56.487 回答