@@ -21,15 +21,13 @@ public partial class ValidateForm
21
21
/// <see cref="EditContext"/> is determined to be valid.
22
22
/// </summary>
23
23
[ Parameter ]
24
- [ NotNull ]
25
24
public Func < EditContext , Task > ? OnValidSubmit { get ; set ; }
26
25
27
26
/// <summary>
28
27
/// A callback that will be invoked when the form is submitted and the
29
28
/// <see cref="EditContext"/> is determined to be invalid.
30
29
/// </summary>
31
30
[ Parameter ]
32
- [ NotNull ]
33
31
public Func < EditContext , Task > ? OnInvalidSubmit { get ; set ; }
34
32
35
33
/// <summary>
@@ -107,6 +105,11 @@ public partial class ValidateForm
107
105
/// </summary>
108
106
private readonly ConcurrentDictionary < ( string FieldName , Type ModelType ) , ( FieldIdentifier FieldIdentifier , IValidateComponent ValidateComponent ) > _validatorCache = new ( ) ;
109
107
108
+ /// <summary>
109
+ /// 验证组件验证结果缓存
110
+ /// </summary>
111
+ private readonly ConcurrentDictionary < IValidateComponent , List < ValidationResult > > _validateResults = new ( ) ;
112
+
110
113
private string ? DisableAutoSubmitString => ( DisableAutoSubmitFormByEnter . HasValue && DisableAutoSubmitFormByEnter . Value ) ? "true" : null ;
111
114
112
115
/// <summary>
@@ -165,7 +168,7 @@ internal void AddValidator((string FieldName, Type ModelType) key, (FieldIdentif
165
168
/// </summary>
166
169
/// <param name="key"></param>
167
170
/// <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 ) ;
169
172
170
173
/// <summary>
171
174
/// 设置指定字段错误信息
@@ -186,19 +189,21 @@ public void SetError<TModel>(Expression<Func<TModel, object?>> expression, strin
186
189
187
190
private void InternalSetError ( MemberExpression exp , string errorMessage )
188
191
{
189
- var fieldName = exp . Member . Name ;
190
192
if ( exp . Expression != null )
191
193
{
194
+ var fieldName = exp . Member . Name ;
192
195
var modelType = exp . Expression . Type ;
193
196
var validator = _validatorCache . FirstOrDefault ( c => c . Key . ModelType == modelType && c . Key . FieldName == fieldName ) . Value . ValidateComponent ;
194
- if ( validator ! = null )
197
+ if ( validator = = null )
195
198
{
196
- var results = new List < ValidationResult >
197
- {
198
- new ( errorMessage , new string [ ] { fieldName } )
199
- } ;
200
- validator . ToggleMessage ( results ) ;
199
+ return ;
201
200
}
201
+
202
+ var results = new List < ValidationResult >
203
+ {
204
+ new ( errorMessage , [ fieldName ] )
205
+ } ;
206
+ validator . ToggleMessage ( results ) ;
202
207
}
203
208
}
204
209
@@ -213,7 +218,7 @@ public void SetError(string propertyName, string errorMessage)
213
218
{
214
219
var results = new List < ValidationResult >
215
220
{
216
- new ( errorMessage , new string [ ] { fieldName } )
221
+ new ( errorMessage , [ fieldName ] )
217
222
} ;
218
223
validator . ToggleMessage ( results ) ;
219
224
}
@@ -241,7 +246,7 @@ private bool TryGetModelField(string propertyName, [MaybeNullWhen(false)] out Ty
241
246
return propNames . IsEmpty ;
242
247
}
243
248
244
- private bool TryGetValidator ( Type modelType , string fieldName , [ NotNullWhen ( true ) ] out IValidateComponent validator )
249
+ private bool TryGetValidator ( Type modelType , string fieldName , out IValidateComponent validator )
245
250
{
246
251
validator = _validatorCache . FirstOrDefault ( c => c . Key . ModelType == modelType && c . Key . FieldName == fieldName ) . Value . ValidateComponent ;
247
252
return validator != null ;
@@ -256,6 +261,8 @@ private bool TryGetValidator(Type modelType, string fieldName, [NotNullWhen(true
256
261
/// <param name="results"></param>
257
262
internal async Task ValidateObject ( ValidationContext context , List < ValidationResult > results )
258
263
{
264
+ _validateResults . Clear ( ) ;
265
+
259
266
if ( ValidateAllProperties )
260
267
{
261
268
await ValidateProperty ( context , results ) ;
@@ -266,30 +273,29 @@ internal async Task ValidateObject(ValidationContext context, List<ValidationRes
266
273
foreach ( var key in _validatorCache . Keys )
267
274
{
268
275
// 验证 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 )
273
278
{
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 )
277
287
{
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
+ } ;
283
291
284
- // 设置其关联属性字段
285
- var propertyValue = Utility . GetPropertyValue ( fieldIdentifier . Model , fieldIdentifier . FieldName ) ;
292
+ // 设置其关联属性字段
293
+ var propertyValue = Utility . GetPropertyValue ( fieldIdentifier . Model , fieldIdentifier . FieldName ) ;
286
294
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 ) ;
292
296
}
297
+ _validateResults . TryAdd ( validator , messages ) ;
298
+ results . AddRange ( messages ) ;
293
299
}
294
300
295
301
// 验证 IValidatableObject
@@ -306,22 +312,28 @@ internal async Task ValidateObject(ValidationContext context, List<ValidationRes
306
312
}
307
313
if ( validate != null )
308
314
{
309
- var messages = validate . Validate ( context ) ;
310
- if ( messages . Any ( ) )
315
+ var messages = validate . Validate ( context ) . ToList ( ) ;
316
+ if ( messages . Count > 0 )
311
317
{
312
318
foreach ( var key in _validatorCache . Keys )
313
319
{
314
320
var validatorValue = _validatorCache [ key ] ;
315
321
var validator = validatorValue . ValidateComponent ;
316
322
if ( validator . IsNeedValidate )
317
323
{
318
- validator . ToggleMessage ( messages ) ;
324
+ _validateResults [ validator ] . AddRange ( messages ) ;
319
325
}
320
326
}
321
327
results . AddRange ( messages ) ;
322
328
}
323
329
}
324
330
}
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
+ }
325
337
}
326
338
}
327
339
@@ -425,7 +437,7 @@ private void ValidateDataAnnotations(object? value, ValidationContext context, L
425
437
var errorMessage = ! string . IsNullOrEmpty ( rule . ErrorMessage ) && rule . ErrorMessage . Contains ( "{0}" )
426
438
? rule . FormatErrorMessage ( displayName )
427
439
: rule . ErrorMessage ;
428
- results . Add ( new ValidationResult ( errorMessage , new string [ ] { memberName } ) ) ;
440
+ results . Add ( new ValidationResult ( errorMessage , [ memberName ] ) ) ;
429
441
}
430
442
}
431
443
}
@@ -507,7 +519,7 @@ private async Task ValidateAsync(IValidateComponent validator, ValidationContext
507
519
if ( messages . Count == 0 )
508
520
{
509
521
// 自定义验证组件
510
- _tcs = new ( ) ;
522
+ _tcs = new TaskCompletionSource < bool > ( ) ;
511
523
await validator . ValidatePropertyAsync ( propertyValue , context , messages ) ;
512
524
_tcs . TrySetResult ( messages . Count == 0 ) ;
513
525
}
@@ -527,8 +539,8 @@ private async Task ValidateAsync(IValidateComponent validator, ValidationContext
527
539
if ( validate != null )
528
540
{
529
541
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 ( ) ) ;
532
544
}
533
545
}
534
546
}
0 commit comments