Asp.net mvc MVC禁用特定验证器的不引人注目的验证
我目前正在构建一个MVC4项目,它通过数据注释使用不引人注目的验证 我有一个特定的字段“PostalCode”,它既是[必需的],又附加了一个[正则表达式]验证器。 问题是,只有在选择了特定的国家/地区时,才应该验证此正则表达式。(此国家/地区将是默认值,我们可以假设在几乎所有情况下都将使用此值) 现在,我需要一些方法在选择其他国家/地区时禁用此正则表达式验证,同时保持所需的验证程序处于活动状态 我找到的几乎所有解决方案都使用jQuery.validator.defaults.ignore过滤器,但这将禁用该项上的两个验证程序 有没有关于如何最好地解决这个问题的想法 编辑:显示其工作原理的小代码段Asp.net mvc MVC禁用特定验证器的不引人注目的验证,asp.net-mvc,jquery-validate,unobtrusive-validation,Asp.net Mvc,Jquery Validate,Unobtrusive Validation,我目前正在构建一个MVC4项目,它通过数据注释使用不引人注目的验证 我有一个特定的字段“PostalCode”,它既是[必需的],又附加了一个[正则表达式]验证器。 问题是,只有在选择了特定的国家/地区时,才应该验证此正则表达式。(此国家/地区将是默认值,我们可以假设在几乎所有情况下都将使用此值) 现在,我需要一些方法在选择其他国家/地区时禁用此正则表达式验证,同时保持所需的验证程序处于活动状态 我找到的几乎所有解决方案都使用jQuery.validator.defaults.ignore过滤器
[Required]
[RegularExpression("^[1-9]\\d{3} ?[a-zA-Z]{2}$"] //Should only be verified if Country == "The Netherlands"
string PostalCode{get;set;}
[Required]
string Country {get;set;}
看起来您需要一个“required if”验证属性。我想检查一下-它有一个实现,您可以像这样使用(直接从项目的网站上获取):
看起来您需要一个“required if”验证属性。我想检查一下-它有一个实现,您可以像这样使用(直接从项目的网站上获取):
看看这个,我自己没用过,但它似乎适合你的需要 他们有这样一个例子:
[RequiredIf("Country", Operator.RegExMatch, "(1033|4105)", ErrorMessage = "{0} is required")]
public string State { get; set; }
[Required(ErrorMessage = "{0} is required")]
public int Country { get; set; }
看看这个,我自己没用过,但它似乎适合你的需要 他们有这样一个例子:
[RequiredIf("Country", Operator.RegExMatch, "(1033|4105)", ErrorMessage = "{0} is required")]
public string State { get; set; }
[Required(ErrorMessage = "{0} is required")]
public int Country { get; set; }
最后,我根据这篇博文创建了自己的ValidationAttribute: 这是一个优雅的解决方案,所需的工作量比我预期的要少 编辑:根据要求,我提供自己创建的解决方案:
// DependentRegularExpressionAttribute.cs
/// <summary>
/// Only performs a regular expression validation if a specified other property meets a validation requirement
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class DependentRegularExpressionAttribute : ValidationAttribute, IClientValidatable
{
private readonly Regex _regex;
private readonly string _otherPropertyName;
private readonly Regex _otherPropertyRegex;
public DependentRegularExpressionAttribute(string regex, string otherPropertyName, string otherPropertyRegex)
{
_regex = new Regex(regex);
_otherPropertyName = otherPropertyName;
_otherPropertyRegex = new Regex(otherPropertyRegex);
}
/// <summary>
/// Format the error message filling in the name of the property to validate and the reference one.
/// </summary>
/// <param name="name">The name of the property to validate</param>
/// <returns>The formatted error message</returns>
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name, _regex, _otherPropertyName, _otherPropertyRegex);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var validationResult = ValidationResult.Success;
if (value == null || String.IsNullOrEmpty(value as string))
return validationResult;
// Using reflection we can get a reference to the other property
var otherPropertyInfo = validationContext.ObjectType.GetProperty(_otherPropertyName);
var otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
if (otherPropertyValue == null || String.IsNullOrEmpty(otherPropertyValue as string))
return validationResult;
if (_otherPropertyRegex.IsMatch(otherPropertyValue.ToString()))
{
if (!_regex.IsMatch(value.ToString()))
validationResult = new ValidationResult(ErrorMessage);
}
return validationResult;
}
#region IClientValidatable Members
/// <summary>
///
/// </summary>
/// <param name="metadata"></param>
/// <param name="context"></param>
/// <returns></returns>
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
string errorMessage = FormatErrorMessage(metadata.DisplayName ?? metadata.PropertyName);
// The value we set here are needed by the jQuery adapter
var dependentRegexRule = new ModelClientValidationRule
{
ErrorMessage = errorMessage,
ValidationType = "dependentregex"
};
//"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE!
dependentRegexRule.ValidationParameters.Add("otherpropertyname", _otherPropertyName);
dependentRegexRule.ValidationParameters.Add("regex", _regex);
dependentRegexRule.ValidationParameters.Add("otherpropertyregex", _otherPropertyRegex);
yield return dependentRegexRule;
}
#endregion
}
// customvalidation.js
$.validator.addMethod("dependentregex", function (value, element, params) {
var regex = new RegExp(params[0]);
var otherElement = document.getElementById(params[1]);
var otherElementRegex = new RegExp(params[2]);
if (!value || !otherElement.value)
return true;
if (otherElementRegex.test(otherElement.value)) {
if (!regex.test(element.value))
return false;
}
return true;
});
$.validator.unobtrusive.adapters.add("dependentregex", ["regex", "otherpropertyname", "otherpropertyregex"], function(options) {
options.rules["dependentregex"] = [options.params.regex,
options.params.otherpropertyname,
options.params.otherpropertyregex];
options.messages["dependentregex"] = options.message;
});
最后,customvalidation.js方法基本上完成了与C#代码完全相同的工作。在我引用的blogpost中可以找到关于一切功能的详细解释。最后,我根据这篇blog post编写了自己的ValidationAttribute: 这是一个优雅的解决方案,所需的工作量比我预期的要少 编辑:根据要求,我提供自己创建的解决方案:
// DependentRegularExpressionAttribute.cs
/// <summary>
/// Only performs a regular expression validation if a specified other property meets a validation requirement
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class DependentRegularExpressionAttribute : ValidationAttribute, IClientValidatable
{
private readonly Regex _regex;
private readonly string _otherPropertyName;
private readonly Regex _otherPropertyRegex;
public DependentRegularExpressionAttribute(string regex, string otherPropertyName, string otherPropertyRegex)
{
_regex = new Regex(regex);
_otherPropertyName = otherPropertyName;
_otherPropertyRegex = new Regex(otherPropertyRegex);
}
/// <summary>
/// Format the error message filling in the name of the property to validate and the reference one.
/// </summary>
/// <param name="name">The name of the property to validate</param>
/// <returns>The formatted error message</returns>
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name, _regex, _otherPropertyName, _otherPropertyRegex);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var validationResult = ValidationResult.Success;
if (value == null || String.IsNullOrEmpty(value as string))
return validationResult;
// Using reflection we can get a reference to the other property
var otherPropertyInfo = validationContext.ObjectType.GetProperty(_otherPropertyName);
var otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
if (otherPropertyValue == null || String.IsNullOrEmpty(otherPropertyValue as string))
return validationResult;
if (_otherPropertyRegex.IsMatch(otherPropertyValue.ToString()))
{
if (!_regex.IsMatch(value.ToString()))
validationResult = new ValidationResult(ErrorMessage);
}
return validationResult;
}
#region IClientValidatable Members
/// <summary>
///
/// </summary>
/// <param name="metadata"></param>
/// <param name="context"></param>
/// <returns></returns>
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
string errorMessage = FormatErrorMessage(metadata.DisplayName ?? metadata.PropertyName);
// The value we set here are needed by the jQuery adapter
var dependentRegexRule = new ModelClientValidationRule
{
ErrorMessage = errorMessage,
ValidationType = "dependentregex"
};
//"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE!
dependentRegexRule.ValidationParameters.Add("otherpropertyname", _otherPropertyName);
dependentRegexRule.ValidationParameters.Add("regex", _regex);
dependentRegexRule.ValidationParameters.Add("otherpropertyregex", _otherPropertyRegex);
yield return dependentRegexRule;
}
#endregion
}
// customvalidation.js
$.validator.addMethod("dependentregex", function (value, element, params) {
var regex = new RegExp(params[0]);
var otherElement = document.getElementById(params[1]);
var otherElementRegex = new RegExp(params[2]);
if (!value || !otherElement.value)
return true;
if (otherElementRegex.test(otherElement.value)) {
if (!regex.test(element.value))
return false;
}
return true;
});
$.validator.unobtrusive.adapters.add("dependentregex", ["regex", "otherpropertyname", "otherpropertyregex"], function(options) {
options.rules["dependentregex"] = [options.params.regex,
options.params.otherpropertyname,
options.params.otherpropertyregex];
options.messages["dependentregex"] = options.message;
});
最后,customvalidation.js方法基本上完成了与C#代码完全相同的工作。关于一切功能的详细解释可以在我引用的博客帖子中找到不完全是,我需要的是一个“regex if”属性。请参阅我的编辑,以获得我想要的更清晰的示例。不完全是,我需要的是一个“regex if”属性。请参阅我的编辑,以获得我想要的更清晰的示例。如上面的答案所示,所需的属性不是条件属性。我需要根据国家的值来切换正则表达式。万无一失似乎并不支持这一点。(至少,我认为是这样,因为他们没有真正可用的文档)您可以实现远程验证吗?并通过所选国家/地区,检查其是否为荷兰,如果不是荷兰,则验证或返回true?正如上面的答案所指出的,所需属性不是条件属性。我需要根据国家的值来切换正则表达式。万无一失似乎并不支持这一点。(至少,我认为是这样,因为他们没有真正可用的文档)您可以实现远程验证吗?并通过所选国家/地区,检查其是否为荷兰,如果不是荷兰,则验证或返回true?你的解决方案可能对其他人有用;你介意在你的答案中贴一个简单的例子吗?你也可以接受你自己的答案。感谢您提供您的实现。您的解决方案可能对其他人有用;你介意在你的答案中贴一个简单的例子吗?你也可以接受你自己的答案。感谢您提供您的实现。