获得具有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; }
您推荐的其他图书馆,还是我可以尝试的其他类型的解决方案?
答案 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; }
希望这可以帮助其他人解决这个问题。