asp.net中的条件正则表达式验证器

asp.net中的条件正则表达式验证器,asp.net,validation,Asp.net,Validation,获取了一个具有数据批注验证程序属性的属性的模型。一个典型的例子是: [RegularExpression("^[a-z]{5,}$", ErrorMessage="required field, must have correct format")] public string SomeProperty {get;set; } 我需要将这些验证器设置为有条件的:如果模型中的特定属性具有某个值,则应禁用大多数验证器-在服务器端和客户端上。( (我使用的是标准的Ms Ajax客户端验证) 没有

获取了一个具有数据批注验证程序属性的属性的模型。一个典型的例子是:

 [RegularExpression("^[a-z]{5,}$", ErrorMessage="required field, must have correct format")]
 public string SomeProperty {get;set; }
我需要将这些验证器设置为有条件的:如果模型中的特定属性具有某个值,则应禁用大多数验证器-在服务器端和客户端上。( (我使用的是标准的Ms Ajax客户端验证)

没有使数据注释验证器有条件的默认方法,因此我四处寻找了一些实现新类型数据注释验证器的库。 查看了sweelproof.codeplex.com和RequiredIf验证属性。 但我发现我要么不能正确地实现它们,要么它们的实现过于简单(万无一失只允许检查一个条件)

对我来说,最好的解决方案是为验证器提供两个参数:一个条件表达式和一个验证器

 [RequiredIf("OtherProperty == true", RegularExpression=@"^[a-z]{5,}$", ErrorMessage="required field, must have correct format")]
 public string SomeProperty {get;set; }
您还推荐其他库吗,或者我可以尝试其他类型的解决方案


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

您需要实现
Validate
方法

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{

    if (condition)
        yield return new ValidationResult("Your error message", new string[] { "Info" });
}
公共IEnumerable验证(ValidationContext ValidationContext) { 如果(条件) 返回新的ValidationResult(“您的错误消息”,新字符串[]{“Info”}); }
是的,无法有条件地使用属性进行内置验证。原因很简单,属性不是可选的

我建议你试试:


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

看起来您希望使用万无一失的验证器。

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

最后,我为它创建了一个新的自定义属性,这是我的实现,效果非常好

  • 创建一个新类:

    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文件“customvalidation.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>

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

这将迫使我为客户端验证添加单独的规则。我不希望这样做。我喜欢能够在一个地方编写验证规则,然后在服务器端和客户端之间“同步”。
    <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; }