我为我的MVC项目创建了一个自定义验证属性,允许我根据动态范围进行验证:
public class DynamicRangeAttribute : ValidationAttribute
{
private readonly double _min;
private readonly double _max;
...
private DynamicRangeAttribute(double? min, double? max, string minProperty, string maxProperty)
{
_min = min ?? (double)GetValue<Decimal>(this, minProperty);
_max = max ?? (double)GetValue<Decimal>(this, maxProperty);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return new RangeAttribute(_min, _max).IsValid(value) ? ValidationResult.Success
: new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
public override string FormatErrorMessage(string name)
{
return string.Format("{0} must be between {1} and {2}", name, _min, _max);
}
...
}
GetValue()使用反射来查找提供的字段的值。
这是实现属性的地方:
[Display(Name = @"Chosen Amount")]
[DynamicRange(0, "CurrentBalance")]
public decimal ChosenAmount { get; set; }
验证本身效果很好,但ErrorMessage不匹配。从理论上讲,它应该显示(例如)“选择的数量必须在0到2500之间”或者当前的余额。相反,我得到了这个:
这不仅与我的自定义错误消息不匹配,而且它也与默认的Range错误消息不匹配(另外,请注意它是拉取字段的实际名称而不是DisplayName)。为了测试它,我尝试在IsValid方法中手动执行验证(基本上返回_min&lt; = value&lt; = _max ),以防Range属性以某种方式覆盖,没有骰子。< / p>
我现在唯一的理论是它与我们格式化字段的方式有关:我们使用javascript将值掩盖为货币,因此2500变为$ 2500.00,-5变为($ 5.00)。我还没有尝试过禁用此功能(这是我的下一步),但我希望有人可能会遇到此问题并提供更好的解决方案。
谢谢,
答案 0 :(得分:1)
此错误消息与您的自定义验证属性无关。显示的原因是decimal
字段的number验证失败。只要您使用$
符号屏蔽输入,就不能再将其视为有效数字,因此您会看到错误。
要解决此问题,请停止屏蔽此字段或删除number
验证规则:
$("#input").rules("remove", "number");
另外,您应该知道,如果以$xxx
格式发布此字段,服务器验证也会失败,因为DefaultModelBinder
无法将此字段转换为{{1 }类型。在这种情况下,您必须为decimal
创建自己的模型绑定器。