2014-07-10 2 views
1

System.ComponentModel.DataAnnotations를 사용하여 일부 데이터 유효성 검사를 수행하여 항목의 제공 가격이 1 $ ~ $ 1,000,000. 나는 ItemPrice라는 클래스를 생성하고 다음과 같은 특성으로 장식했습니다.net의 데이터 주석은 소수 값으로 지정된 범위의 유효성을 검사하지 못합니다.

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); 
     } 
    } 
+1

오류 메시지를 추가하십시오. ErrorMessage = "{0}의 값은 {1}에서 {2} 사이 여야합니다." – Ehsan

+0

주석은 ModelState.IsValid를 통해 MVC에서 올바르게 작동합니다. ASP.NET MVC 외부에 있다고 가정합니까? 그렇다면 ItemPrice의 메타 데이터에 대한 버디 클래스를 다른 곳에서 사용하고 있습니까? –

+0

예, 안정적인 서비스를 위해 유효성 검사가 웹 API 프로젝트에서 사용되고 있습니다. – user3507823

답변

3

System.Decimal은 CLR의 추악한 단계 자식입니다. Int32와 같이 기본 유형으로 간주하지 않습니다. 가장 심각한 문제는 CLR이 작동해야하는 방식 인 Golden Standard 인 CLI spec이 Decimal의 내부 형식을 결정하지 못한다는 것입니다. 구현 세부 사항으로 남겨 두었습니다.

CLI 스펙에 Decimal이 어떻게 표시되어야하는지에 대한 상당한 논쟁이있었습니다. 우리가 사용하는 것은 .NET이 등장하기 오래 전에 정의 된 것입니다. 그러나 IEEE-754 standard의 배경 소음이 눈에 띄었으므로 표준 10 진수 형식을 사용하기를 원했습니다. 표준을 설정하려는 사람의 고전적인 문제로 어려움을 겪은 표준은 방금 다른 것을 추가했습니다. 그리고 15 년 후에도 모든 사람들이 여전히 무시하고 있습니다. 칩 제조업체를 포함하여 모든 사람들에게 표준 N + 1을 채택 할 정당한 이유를 부여해야합니다.

이 작업은 수행되지 않으며, 퀵 샌드에서 표준 CLI를 만들 수 없습니다. 따라서 CLR은 이 아니며 Decimal 인수를 사용하는 특성 생성자를 지원하지 않습니다. 이들의 값은 메타 데이터로 인코딩되며 메타 데이터에 대한 바이너리 표준은 매우 중요한 하이퍼입니다.

해결 방법은 간단합니다. 합리적인 금액의 경우 십진법 값에 100을 곱한 정수형을 대신 사용하십시오. 범위 또는 소수 자릿수를 얻으려면 System.Double을 사용하십시오. 관대함에 틀림 없으므로 아무도 1E-15까지 나가기를 좋아하지 않으며 그것에 대해 생각 나게됩니다. 단순히 속성 생성자에서 Decimal로 변환 할 수 있습니다.

관련 문제