@@ -21,15 +21,13 @@ public partial class ValidateForm
2121 /// <see cref="EditContext"/> is determined to be valid.
2222 /// </summary>
2323 [ Parameter ]
24- [ NotNull ]
2524 public Func < EditContext , Task > ? OnValidSubmit { get ; set ; }
2625
2726 /// <summary>
2827 /// A callback that will be invoked when the form is submitted and the
2928 /// <see cref="EditContext"/> is determined to be invalid.
3029 /// </summary>
3130 [ Parameter ]
32- [ NotNull ]
3331 public Func < EditContext , Task > ? OnInvalidSubmit { get ; set ; }
3432
3533 /// <summary>
@@ -107,6 +105,11 @@ public partial class ValidateForm
107105 /// </summary>
108106 private readonly ConcurrentDictionary < ( string FieldName , Type ModelType ) , ( FieldIdentifier FieldIdentifier , IValidateComponent ValidateComponent ) > _validatorCache = new ( ) ;
109107
108+ /// <summary>
109+ /// 验证组件验证结果缓存
110+ /// </summary>
111+ private readonly ConcurrentDictionary < IValidateComponent , List < ValidationResult > > _validateResults = new ( ) ;
112+
110113 private string ? DisableAutoSubmitString => ( DisableAutoSubmitFormByEnter . HasValue && DisableAutoSubmitFormByEnter . Value ) ? "true" : null ;
111114
112115 /// <summary>
@@ -165,7 +168,7 @@ internal void AddValidator((string FieldName, Type ModelType) key, (FieldIdentif
165168 /// </summary>
166169 /// <param name="key"></param>
167170 /// <param name="value"></param>
168- internal bool TryRemoveValidator ( ( string FieldName , Type ModelType ) key , [ MaybeNullWhen ( false ) ] out ( FieldIdentifier FieldIdentifier , IValidateComponent IValidateComponent ) value ) => _validatorCache . TryRemove ( key , out value ) ;
171+ internal bool TryRemoveValidator ( ( string FieldName , Type ModelType ) key , out ( FieldIdentifier FieldIdentifier , IValidateComponent IValidateComponent ) value ) => _validatorCache . TryRemove ( key , out value ) ;
169172
170173 /// <summary>
171174 /// 设置指定字段错误信息
@@ -186,19 +189,21 @@ public void SetError<TModel>(Expression<Func<TModel, object?>> expression, strin
186189
187190 private void InternalSetError ( MemberExpression exp , string errorMessage )
188191 {
189- var fieldName = exp . Member . Name ;
190192 if ( exp . Expression != null )
191193 {
194+ var fieldName = exp . Member . Name ;
192195 var modelType = exp . Expression . Type ;
193196 var validator = _validatorCache . FirstOrDefault ( c => c . Key . ModelType == modelType && c . Key . FieldName == fieldName ) . Value . ValidateComponent ;
194- if ( validator ! = null )
197+ if ( validator = = null )
195198 {
196- var results = new List < ValidationResult >
197- {
198- new ( errorMessage , new string [ ] { fieldName } )
199- } ;
200- validator . ToggleMessage ( results ) ;
199+ return ;
201200 }
201+
202+ var results = new List < ValidationResult >
203+ {
204+ new ( errorMessage , [ fieldName ] )
205+ } ;
206+ validator . ToggleMessage ( results ) ;
202207 }
203208 }
204209
@@ -213,7 +218,7 @@ public void SetError(string propertyName, string errorMessage)
213218 {
214219 var results = new List < ValidationResult >
215220 {
216- new ( errorMessage , new string [ ] { fieldName } )
221+ new ( errorMessage , [ fieldName ] )
217222 } ;
218223 validator . ToggleMessage ( results ) ;
219224 }
@@ -241,7 +246,7 @@ private bool TryGetModelField(string propertyName, [MaybeNullWhen(false)] out Ty
241246 return propNames . IsEmpty ;
242247 }
243248
244- private bool TryGetValidator ( Type modelType , string fieldName , [ NotNullWhen ( true ) ] out IValidateComponent validator )
249+ private bool TryGetValidator ( Type modelType , string fieldName , out IValidateComponent validator )
245250 {
246251 validator = _validatorCache . FirstOrDefault ( c => c . Key . ModelType == modelType && c . Key . FieldName == fieldName ) . Value . ValidateComponent ;
247252 return validator != null ;
@@ -256,6 +261,8 @@ private bool TryGetValidator(Type modelType, string fieldName, [NotNullWhen(true
256261 /// <param name="results"></param>
257262 internal async Task ValidateObject ( ValidationContext context , List < ValidationResult > results )
258263 {
264+ _validateResults . Clear ( ) ;
265+
259266 if ( ValidateAllProperties )
260267 {
261268 await ValidateProperty ( context , results ) ;
@@ -266,30 +273,29 @@ internal async Task ValidateObject(ValidationContext context, List<ValidationRes
266273 foreach ( var key in _validatorCache . Keys )
267274 {
268275 // 验证 DataAnnotations
269- var validatorValue = _validatorCache [ key ] ;
270- var validator = validatorValue . ValidateComponent ;
271- var fieldIdentifier = validatorValue . FieldIdentifier ;
272- if ( validator . IsNeedValidate )
276+ var ( fieldIdentifier , validator ) = _validatorCache [ key ] ;
277+ if ( ! validator . IsNeedValidate )
273278 {
274- var messages = new List < ValidationResult > ( ) ;
275- var pi = key . ModelType . GetPropertyByName ( key . FieldName ) ;
276- if ( pi != null )
279+ continue ;
280+ }
281+
282+ var messages = new List < ValidationResult > ( ) ;
283+ var pi = key . ModelType . GetPropertyByName ( key . FieldName ) ;
284+ if ( pi != null )
285+ {
286+ var propertyValidateContext = new ValidationContext ( fieldIdentifier . Model , context , null )
277287 {
278- var propertyValidateContext = new ValidationContext ( fieldIdentifier . Model , context , null )
279- {
280- MemberName = fieldIdentifier . FieldName ,
281- DisplayName = fieldIdentifier . GetDisplayName ( )
282- } ;
288+ MemberName = fieldIdentifier . FieldName ,
289+ DisplayName = fieldIdentifier . GetDisplayName ( )
290+ } ;
283291
284- // 设置其关联属性字段
285- var propertyValue = Utility . GetPropertyValue ( fieldIdentifier . Model , fieldIdentifier . FieldName ) ;
292+ // 设置其关联属性字段
293+ var propertyValue = Utility . GetPropertyValue ( fieldIdentifier . Model , fieldIdentifier . FieldName ) ;
286294
287- await ValidateAsync ( validator , propertyValidateContext , messages , pi , propertyValue ) ;
288- }
289- // 客户端提示
290- validator . ToggleMessage ( messages ) ;
291- results . AddRange ( messages ) ;
295+ await ValidateAsync ( validator , propertyValidateContext , messages , pi , propertyValue ) ;
292296 }
297+ _validateResults . TryAdd ( validator , messages ) ;
298+ results . AddRange ( messages ) ;
293299 }
294300
295301 // 验证 IValidatableObject
@@ -306,22 +312,28 @@ internal async Task ValidateObject(ValidationContext context, List<ValidationRes
306312 }
307313 if ( validate != null )
308314 {
309- var messages = validate . Validate ( context ) ;
310- if ( messages . Any ( ) )
315+ var messages = validate . Validate ( context ) . ToList ( ) ;
316+ if ( messages . Count > 0 )
311317 {
312318 foreach ( var key in _validatorCache . Keys )
313319 {
314320 var validatorValue = _validatorCache [ key ] ;
315321 var validator = validatorValue . ValidateComponent ;
316322 if ( validator . IsNeedValidate )
317323 {
318- validator . ToggleMessage ( messages ) ;
324+ _validateResults [ validator ] . AddRange ( messages ) ;
319325 }
320326 }
321327 results . AddRange ( messages ) ;
322328 }
323329 }
324330 }
331+
332+ ValidMemberNames . RemoveAll ( name => _validateResults . Values . SelectMany ( i => i ) . Any ( i => i . MemberNames . Contains ( name ) ) ) ;
333+ foreach ( var ( validator , messages ) in _validateResults )
334+ {
335+ validator . ToggleMessage ( messages ) ;
336+ }
325337 }
326338 }
327339
@@ -425,7 +437,7 @@ private void ValidateDataAnnotations(object? value, ValidationContext context, L
425437 var errorMessage = ! string . IsNullOrEmpty ( rule . ErrorMessage ) && rule . ErrorMessage . Contains ( "{0}" )
426438 ? rule . FormatErrorMessage ( displayName )
427439 : rule . ErrorMessage ;
428- results . Add ( new ValidationResult ( errorMessage , new string [ ] { memberName } ) ) ;
440+ results . Add ( new ValidationResult ( errorMessage , [ memberName ] ) ) ;
429441 }
430442 }
431443 }
@@ -507,7 +519,7 @@ private async Task ValidateAsync(IValidateComponent validator, ValidationContext
507519 if ( messages . Count == 0 )
508520 {
509521 // 自定义验证组件
510- _tcs = new ( ) ;
522+ _tcs = new TaskCompletionSource < bool > ( ) ;
511523 await validator . ValidatePropertyAsync ( propertyValue , context , messages ) ;
512524 _tcs . TrySetResult ( messages . Count == 0 ) ;
513525 }
@@ -527,8 +539,8 @@ private async Task ValidateAsync(IValidateComponent validator, ValidationContext
527539 if ( validate != null )
528540 {
529541 messages . AddRange ( validate . Validate ( context ) ) ;
530- ValidMemberNames . AddRange ( validate . ValidMemberNames ( ) ) ;
531- InvalidMemberNames . AddRange ( validate . InvalidMemberNames ( ) ) ;
542+ ValidMemberNames . AddRange ( validate . GetValidMemberNames ( ) ) ;
543+ InvalidMemberNames . AddRange ( validate . GetInvalidMemberNames ( ) ) ;
532544 }
533545 }
534546 }
0 commit comments