如何在客户端验证中验证双变量规则?
How can I validate two-variable rules in client-side validation?
我有以下 poco:
public class CabinetItem
{
[Required]
[Display(...)]
public double Width { get; set; }
public double MinWidth { get; }
}
我想弄清楚的是,当 MinWidth
可能是任何东西时,我如何验证 Width
大于 MinWidth
?最小宽度是一个依赖于橱柜项目的约束。注意:还有一个 MaxWidth
我为了简化这个问题而省略了。
选项 1:
foolproof nuget 包可能对您的情况非常有用。
安装 foolproof nuget 包并使用其额外的有用属性,如下所示:
public class CabinetItem
{
[Required]
[Display(...)]
[GreaterThan("MinWidth")]
public double Width { get; set; }
public double MinWidth { get; }
}
还有其他功能:
- [是]
- [等于]
- [不等于]
- [大于]
- [小于]
- [大于或等于]
- [小于或等于]
资源: Is there a way through data annotations to verify that one date property is greater than or equal to another date property?
您可以创建 CustomValidationAttribute
以此为例:
public class GreaterThanAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _testedPropertyName;
private readonly bool _allowEqualValues;
private readonly string _testedPropertyDisplayName;
public override string FormatErrorMessage(string displayName)
{
return string.Format(ErrorMessages.GreaterThan_Message, displayName, _testedPropertyDisplayName);
}
public GreaterThanAttribute(string testedPropertyName, Type resourceType, string testedPropertyDisplayNameKey, bool allowEqualValues = false)
{
_testedPropertyName = testedPropertyName;
_allowEqualValues = allowEqualValues;
var rm = new ResourceManager(resourceType);
_testedPropertyDisplayName = rm.GetString(testedPropertyDisplayNameKey);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propertyTestedInfo = validationContext.ObjectType.GetProperty(_testedPropertyName);
if (propertyTestedInfo == null)
{
return new ValidationResult(string.Format("unknown property {0}", _testedPropertyName));
}
var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);
if (value == null || !(value is Decimal))
{
return ValidationResult.Success;
}
if (propertyTestedValue == null || !(propertyTestedValue is Decimal))
{
return ValidationResult.Success;
}
// Compare values
if ((Decimal)value >= (Decimal)propertyTestedValue)
{
if (_allowEqualValues && value == propertyTestedValue)
{
return ValidationResult.Success;
}
else if ((Decimal)value > (Decimal)propertyTestedValue)
{
return ValidationResult.Success;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "greaterthan"
};
rule.ValidationParameters["propertytested"] = _testedPropertyName;
rule.ValidationParameters["allowequalvalues"] = _allowEqualValues;
yield return rule;
}
}
你可以这样使用它:
public Decimal MyProperty1 { get; set; }
[GreaterThanAttribute("MyProperty1", typeof(Strings), "Error_String")]
public Decimal MyProperty2 { get; set; }
[GreaterThanAttribute("MyProperty2", typeof(Strings), "Error_String")]
public Decimal MyProperty3 { get; set; }
并且在客户端,您可以添加此内容以进行客户端验证:
jQuery.validator.unobtrusive.adapters.add('greaterthan', ['propertytested', 'allowequalvalues'], function (options) {
options.params["allowequalvalues"] = options.params["allowequalvalues"] === "True" ||
options.params["allowequalvalues"] === "true" ||
options.params["allowequalvalues"] === true ? true : false;
options.rules['greaterthan'] = options.params;
options.messages['greaterthan'] = options.message;
});
jQuery.validator.addMethod("greaterthan", function (value, element, params) {
var properyTestedvalue= $('input[name="' + params.propertytested + '"]').val();
if (!value || !properyTestedvalue) return true;
return (params.allowequalvalues) ? parseFloat(properyTestedvalue) <= parseFloat(value) : parseFloat(properyTestedvalue) < parseFloat(value);
}, '');
我有以下 poco:
public class CabinetItem
{
[Required]
[Display(...)]
public double Width { get; set; }
public double MinWidth { get; }
}
我想弄清楚的是,当 MinWidth
可能是任何东西时,我如何验证 Width
大于 MinWidth
?最小宽度是一个依赖于橱柜项目的约束。注意:还有一个 MaxWidth
我为了简化这个问题而省略了。
选项 1:
foolproof nuget 包可能对您的情况非常有用。
安装 foolproof nuget 包并使用其额外的有用属性,如下所示:
public class CabinetItem
{
[Required]
[Display(...)]
[GreaterThan("MinWidth")]
public double Width { get; set; }
public double MinWidth { get; }
}
还有其他功能:
- [是]
- [等于]
- [不等于]
- [大于]
- [小于]
- [大于或等于]
- [小于或等于]
资源: Is there a way through data annotations to verify that one date property is greater than or equal to another date property?
您可以创建 CustomValidationAttribute
以此为例:
public class GreaterThanAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _testedPropertyName;
private readonly bool _allowEqualValues;
private readonly string _testedPropertyDisplayName;
public override string FormatErrorMessage(string displayName)
{
return string.Format(ErrorMessages.GreaterThan_Message, displayName, _testedPropertyDisplayName);
}
public GreaterThanAttribute(string testedPropertyName, Type resourceType, string testedPropertyDisplayNameKey, bool allowEqualValues = false)
{
_testedPropertyName = testedPropertyName;
_allowEqualValues = allowEqualValues;
var rm = new ResourceManager(resourceType);
_testedPropertyDisplayName = rm.GetString(testedPropertyDisplayNameKey);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propertyTestedInfo = validationContext.ObjectType.GetProperty(_testedPropertyName);
if (propertyTestedInfo == null)
{
return new ValidationResult(string.Format("unknown property {0}", _testedPropertyName));
}
var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);
if (value == null || !(value is Decimal))
{
return ValidationResult.Success;
}
if (propertyTestedValue == null || !(propertyTestedValue is Decimal))
{
return ValidationResult.Success;
}
// Compare values
if ((Decimal)value >= (Decimal)propertyTestedValue)
{
if (_allowEqualValues && value == propertyTestedValue)
{
return ValidationResult.Success;
}
else if ((Decimal)value > (Decimal)propertyTestedValue)
{
return ValidationResult.Success;
}
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.DisplayName),
ValidationType = "greaterthan"
};
rule.ValidationParameters["propertytested"] = _testedPropertyName;
rule.ValidationParameters["allowequalvalues"] = _allowEqualValues;
yield return rule;
}
}
你可以这样使用它:
public Decimal MyProperty1 { get; set; }
[GreaterThanAttribute("MyProperty1", typeof(Strings), "Error_String")]
public Decimal MyProperty2 { get; set; }
[GreaterThanAttribute("MyProperty2", typeof(Strings), "Error_String")]
public Decimal MyProperty3 { get; set; }
并且在客户端,您可以添加此内容以进行客户端验证:
jQuery.validator.unobtrusive.adapters.add('greaterthan', ['propertytested', 'allowequalvalues'], function (options) {
options.params["allowequalvalues"] = options.params["allowequalvalues"] === "True" ||
options.params["allowequalvalues"] === "true" ||
options.params["allowequalvalues"] === true ? true : false;
options.rules['greaterthan'] = options.params;
options.messages['greaterthan'] = options.message;
});
jQuery.validator.addMethod("greaterthan", function (value, element, params) {
var properyTestedvalue= $('input[name="' + params.propertytested + '"]').val();
if (!value || !properyTestedvalue) return true;
return (params.allowequalvalues) ? parseFloat(properyTestedvalue) <= parseFloat(value) : parseFloat(properyTestedvalue) < parseFloat(value);
}, '');