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, ""); } }
<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; }