[英]Data Annotations in .net fail to validate a range specified for a decimal value
我正在尝试使用System.ComponentModel.DataAnnotations执行一些数据验证,以验证项目的报价是否在1 $到$ 1,000,000的范围内。 我创建了一个名为ItemPrice的类,并使用以下属性进行装饰:
public class ItemPrice
{
[Required (ErrorMessage = "Name is required")]
public string Name
{
get;
set;
}
[Range(1.00,1000000.00)]
public decimal Price
{
get;
set;
}
}
后来我尝试验证此类的实例,其中ItemPrice.Price设置为0.0。 以下代码正确确定是否省略了Name值,但从未检测到已输入小于1的价格。 任何人都可以告诉我为什么以下代码无法检测到1到1,000,000范围之外的价格?
private void validateMessage(object message)
{
if (message == null)
{
throw new ArgumentNullException("message null");
}
var context = new ValidationContext(message, serviceProvider: null, items: null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(message, context, results);
var sb = new StringBuilder();
if (!isValid)
{
foreach (var validationResult in results)
{
Trace.WriteLine(validationResult.ErrorMessage);
if (sb.Length > 0)
sb.Append("\n");
sb.Append(validationResult.ErrorMessage);
}
Exception innerException = new Exception(sb.ToString());
throw new ArgumentException("Invalid argument(s) in message", innerException);
}
}
System.Decimal是CLR丑陋的继子。 它不认为它是主要类型,如Int32等。 最严重的问题是CLI规范 ,CLR需要工作的黄金标准,并没有确定Decimal的内部格式。 它留作了一个实现细节。
在编写CLI规范时,Decimal应该是什么样子,这引起了相当大的争议。 我们今天使用的是在.NET出现之前很久就定义的那个。 但是, IEEE-754标准中存在相当大的背景噪声,这些噪声也需要确定标准的十进制格式。 一个标准遭遇任何人试图设定标准的经典问题,它只是添加了另一个。 15年后,每个人仍然会忽视这一点。 包括芯片制造商在内,他们需要首先让每个人都有充分的理由采用标准N + 1。
这不行,您无法在流沙上创建标准CLI。 因此,CLR 不支持采取十进制的参数属性的构造函数。 它们的值被编码到元数据中,并且具有元数据的二进制标准是超级重要的超级重要。
解决方法很简单。 使用整数类型,十进制值乘以100以获得合理的货币价值。 如果您确实需要使用System.Double,则必须获取范围或小数位数。 一定要宽容,没有人喜欢在1E-15之前离开并被提醒。 您可以在属性构造函数中简单地转换为Decimal。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.