.net中的数据注释无法验证为十进制值指定的范围

本文关键字:十进制 范围 数据 注释 net 验证 | 更新日期: 2023-09-27 18:12:36

我正在尝试使用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。价格设置为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);
        }
    }

.net中的数据注释无法验证为十进制值指定的范围

系统。十进制是CLR丑陋的继子。它不认为它是主类型,像Int32等。最严重的问题是CLI规范(CLR工作方式的黄金标准)没有确定Decimal的内部格式。它被留作实现细节。

在编写CLI规范时,关于Decimal应该是什么样子存在相当大的争论。我们今天使用的是早在。net出现之前就定义的。但是,来自IEEE-754标准的相当大的背景噪音也想要确定一个标准的十进制格式。这个标准遇到了一个经典的问题,那就是任何人都想设立一个标准,它只是增加了一个标准。15年后的今天,所有人仍然忽视了这一点。包括芯片制造商在内,他们需要先给每个人一个采用标准N+1的好理由。

这不行,你不能在流沙上创建一个标准的CLI。所以CLR 不支持接受Decimal参数的属性构造函数。它们的值被编码到元数据中,拥有元数据的二进制标准是非常非常重要的。

解决方法很简单。请使用整型,将十进制值乘以100得到合理的货币值。使用系统。如果你真的,真的需要得到小数的范围,那么就翻倍。一定要宽厚一点,没有人喜欢在15点15分下班时被提醒。您可以在属性构造函数中简单地转换为Decimal。