asp.net中的条件RegularExpression验证器

时间:2013-05-06 03:49:21

标签: asp.net validation

获得具有Data Annotation Validator属性的属性的模型。一个典型的例子是:

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

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

没有默认的方法使数据注释验证器成为条件,所以我查看了一些实现新类型数据注释验证器的库。 查看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 个答案:

答案 0 :(得分:1)

看起来你想要使用来自万无一失的RegularExpressionIf验证器。

答案 1 :(得分:0)

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

您需要实施Validate方法。

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

    if (condition)
        yield return new ValidationResult("Your error message", new string[] { "Info" });
}

答案 2 :(得分:0)

是的,无法通过属性有条件地进行内置验证。仅仅因为属性不是可选的。

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

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

答案 3 :(得分: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文件,&#34; custom-validation.js&#34;就我而言,进入你的观点。

    <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; }
    

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