11using NodaMoney ;
22using System . ComponentModel . DataAnnotations ;
3- using System . Diagnostics . CodeAnalysis ;
4- using System . Globalization ;
53using System . Text . Json ;
64
75namespace NodaMoneyTest ;
@@ -11,11 +9,29 @@ public static class SerializationTest
119
1210 #region Constants & Statics
1311
14- public static void Input_Validation_Test ( )
12+ public static void Input_Validation_ModelState_Test ( )
1513 {
16- var input = new MyInput ( "Jane Doe" , 25 , new FastMoneyDto { Amount = 49.95m , } ) ;
17- var json = JsonSerializer . Serialize ( input ) ;
18- Console . WriteLine ( json ) ;
14+ var input = new MyInput ( "Jane Doe" , 25 , new FastMoneyDto { Amount = 101m , } ) ;
15+ var context = new ValidationContext ( input ) ;
16+ var results = new List < ValidationResult > ( ) ;
17+ var isValid = Validator . TryValidateObject ( input , context , results , true ) ;
18+
19+ Console . WriteLine ( $ "MyInput Over Max IsValid: { isValid } ") ;
20+ foreach ( var result in results )
21+ {
22+ Console . WriteLine ( $ "Error: { result . ErrorMessage } ") ;
23+ }
24+
25+ var input2 = new MyInput ( "Jane Doe" , 25 , new FastMoneyDto { Amount = 1m , Currency = "abc" } ) ;
26+ context = new ValidationContext ( input2 ) ;
27+ results = [ ] ;
28+ isValid = Validator . TryValidateObject ( input2 , context , results , true ) ;
29+
30+ Console . WriteLine ( $ "MyInput Currency IsValid: { isValid } ") ;
31+ foreach ( var result in results )
32+ {
33+ Console . WriteLine ( $ "Error: { result . ErrorMessage } ") ;
34+ }
1935 }
2036
2137 public static void Output_Serialization_Test ( )
@@ -43,105 +59,6 @@ public static void Serialize_Test()
4359
4460public record MyDto ( string Name , int Age , FastMoney Price ) ;
4561
46- public record MyInput ( string Name , int Age , [ AmountValidation ( "1.00000 " , "100" ) ] FastMoneyDto Price ) ;
62+ public record MyInput ( string Name , int Age , [ property : FastMoneyRange ( "1.0000 " , "100" ) ] FastMoneyDto Price ) ;
4763
4864public record MyOutput ( string Name , int Age , FastMoneyDto Price ) ;
49-
50- public static class FastMoneyExtensions
51- {
52-
53- #region Constants & Statics
54-
55- public static FastMoneyDto ToDto ( this FastMoney fastMoney )
56- {
57- return new FastMoneyDto { Amount = fastMoney . Amount , Currency = fastMoney . Currency . Code } ;
58- }
59-
60- #endregion
61-
62- }
63-
64- public class FastMoneyDto : IValidatableObject
65- {
66-
67- #region Properties
68-
69- public decimal Amount { get ; init ; }
70-
71- public string Currency { get ; init ; } = CurrencyCode . CNY ;
72-
73- #endregion
74-
75- #region IValidatableObject implementations
76-
77- public IEnumerable < ValidationResult > Validate ( ValidationContext validationContext )
78- {
79- var results = new List < ValidationResult > ( ) ;
80-
81- //validate AmountValidationAttribute
82- var context = new ValidationContext ( this ) ;
83- _ = Validator . TryValidateProperty ( Amount , context , results ) ;
84-
85- try
86- {
87- _ = CurrencyInfo . FromCode ( Currency ) ;
88- }
89- catch
90- {
91- results . Add ( new ValidationResult ( "Invalid currency code." , [ nameof ( Currency ) ] ) ) ;
92- }
93-
94- return results ;
95- }
96-
97- #endregion
98-
99- }
100-
101- [ AttributeUsage ( AttributeTargets . Property | AttributeTargets . Field | AttributeTargets . Parameter , AllowMultiple = false ) ]
102- public sealed class AmountValidationAttribute : ValidationAttribute
103- {
104- [ SuppressMessage ( "Design" , "CA1019:Define accessors for attribute arguments" , Justification = "<Pending>" ) ]
105- public AmountValidationAttribute ( string minimum , string maximum )
106- {
107- Minimum = decimal . Parse ( minimum , CultureInfo . InvariantCulture ) ;
108- Maximum = decimal . Parse ( maximum , CultureInfo . InvariantCulture ) ;
109-
110- ArgumentOutOfRangeException . ThrowIfLessThan ( Minimum , FastMoney . MinValue . Amount ) ;
111- ArgumentOutOfRangeException . ThrowIfGreaterThan ( Maximum , FastMoney . MaxValue . Amount ) ;
112-
113- if ( Minimum . Scale > 4 )
114- {
115- throw new ArgumentException ( "Scale cannot be greater than 4." , nameof ( minimum ) ) ;
116- }
117- if ( Maximum . Scale > 4 )
118- {
119- throw new ArgumentException ( "Scale cannot be greater than 4." , nameof ( maximum ) ) ;
120- }
121- }
122-
123- #region Properties
124-
125- /// <summary>
126- /// Gets the maximum allowed field value.
127- /// </summary>
128- public decimal Maximum { get ; }
129-
130- /// <summary>
131- /// Specifies whether validation should fail for values that are equal to System.ComponentModel.DataAnnotations.RangeAttribute.Maximum.
132- /// </summary>
133- public bool MaximumIsExclusive { get ; set ; }
134-
135- /// <summary>
136- /// Gets the minimum allowed field value.
137- /// </summary>
138- public decimal Minimum { get ; }
139-
140- /// <summary>
141- /// Specifies whether validation should fail for values that are equal to System.ComponentModel.DataAnnotations.RangeAttribute.Minimum.
142- /// </summary>
143- public bool MinimumIsExclusive { get ; set ; }
144-
145- #endregion
146-
147- }
0 commit comments