[英]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.