@@ -495,6 +495,95 @@ public async Task Validate_RequiredOnPropertyShortCircuitsOtherValidations()
495
495
Assert . Equal ( "The Password field is required." , error . Value . Single ( ) ) ;
496
496
}
497
497
498
+ [ Fact ]
499
+ public async Task Validate_IValidatableObject_WithZeroAndMultipleMemberNames_BehavesAsExpected ( )
500
+ {
501
+ var globalType = new TestValidatableTypeInfo (
502
+ typeof ( GlobalErrorObject ) ,
503
+ [ ] ) ; // no properties – nothing sets MemberName
504
+
505
+ var context = new ValidateContext
506
+ {
507
+ ValidationOptions = new TestValidationOptions ( new Dictionary < Type , ValidatableTypeInfo >
508
+ {
509
+ { typeof ( GlobalErrorObject ) , globalType }
510
+ } )
511
+ } ;
512
+
513
+ var globalErrorInstance = new GlobalErrorObject { Data = - 1 } ;
514
+ context . ValidationContext = new ValidationContext ( globalErrorInstance ) ;
515
+
516
+ await globalType . ValidateAsync ( globalErrorInstance , context , default ) ;
517
+
518
+ Assert . NotNull ( context . ValidationErrors ) ;
519
+ var globalError = Assert . Single ( context . ValidationErrors ) ;
520
+ Assert . Equal ( string . Empty , globalError . Key ) ;
521
+ Assert . Equal ( "Data must be positive." , globalError . Value . Single ( ) ) ;
522
+
523
+ var multiType = new TestValidatableTypeInfo (
524
+ typeof ( MultiMemberErrorObject ) ,
525
+ [
526
+ CreatePropertyInfo ( typeof ( MultiMemberErrorObject ) , typeof ( string ) , "FirstName" , "FirstName" , [ ] ) ,
527
+ CreatePropertyInfo ( typeof ( MultiMemberErrorObject ) , typeof ( string ) , "LastName" , "LastName" , [ ] )
528
+ ] ) ;
529
+
530
+ context . ValidationErrors = [ ] ;
531
+ context . ValidationOptions = new TestValidationOptions ( new Dictionary < Type , ValidatableTypeInfo >
532
+ {
533
+ { typeof ( MultiMemberErrorObject ) , multiType }
534
+ } ) ;
535
+
536
+ var multiErrorInstance = new MultiMemberErrorObject { FirstName = "" , LastName = "" } ;
537
+ context . ValidationContext = new ValidationContext ( multiErrorInstance ) ;
538
+
539
+ await multiType . ValidateAsync ( multiErrorInstance , context , default ) ;
540
+
541
+ Assert . NotNull ( context . ValidationErrors ) ;
542
+ Assert . Collection ( context . ValidationErrors ,
543
+ kvp =>
544
+ {
545
+ Assert . Equal ( "FirstName" , kvp . Key ) ;
546
+ Assert . Equal ( "FirstName and LastName are required." , kvp . Value . First ( ) ) ;
547
+ } ,
548
+ kvp =>
549
+ {
550
+ Assert . Equal ( "LastName" , kvp . Key ) ;
551
+ Assert . Equal ( "FirstName and LastName are required." , kvp . Value . First ( ) ) ;
552
+ } ) ;
553
+ }
554
+
555
+ // Returns no member names to validate https://github.com/dotnet/aspnetcore/issues/61739
556
+ private class GlobalErrorObject : IValidatableObject
557
+ {
558
+ public int Data { get ; set ; }
559
+
560
+ public IEnumerable < ValidationResult > Validate ( ValidationContext validationContext )
561
+ {
562
+ if ( Data <= 0 )
563
+ {
564
+ yield return new ValidationResult ( "Data must be positive." ) ;
565
+ }
566
+ }
567
+ }
568
+
569
+ // Returns multiple member names to validate https://github.com/dotnet/aspnetcore/issues/61739
570
+ private class MultiMemberErrorObject : IValidatableObject
571
+ {
572
+ public string ? FirstName { get ; set ; }
573
+ public string ? LastName { get ; set ; }
574
+
575
+ public IEnumerable < ValidationResult > Validate ( ValidationContext validationContext )
576
+ {
577
+ if ( string . IsNullOrEmpty ( FirstName ) || string . IsNullOrEmpty ( LastName ) )
578
+ {
579
+ // MULTIPLE member names
580
+ yield return new ValidationResult (
581
+ "FirstName and LastName are required." ,
582
+ [ nameof ( FirstName ) , nameof ( LastName ) ] ) ;
583
+ }
584
+ }
585
+ }
586
+
498
587
private ValidatablePropertyInfo CreatePropertyInfo (
499
588
Type containingType ,
500
589
Type propertyType ,
@@ -534,7 +623,7 @@ public IEnumerable<ValidationResult> Validate(ValidationContext validationContex
534
623
{
535
624
if ( Salary < 0 )
536
625
{
537
- yield return new ValidationResult ( "Salary must be a positive value." , new [ ] { nameof ( Salary ) } ) ;
626
+ yield return new ValidationResult ( "Salary must be a positive value." , [ " Salary" ] ) ;
538
627
}
539
628
}
540
629
}
0 commit comments