@@ -60,6 +60,40 @@ public void JsonCustomizedName()
6060 Assert . Equal ( "A field name" , m . FieldName ) ;
6161 }
6262
63+ [ Fact ]
64+ public void NonJsonName_CaseInsensitive ( )
65+ {
66+ var json = @"{
67+ ""HIDING_FIELD_NAME"": ""A field name""
68+ }" ;
69+
70+ var m = AssertReadJson < HelloRequest > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
71+ Assert . Equal ( "A field name" , m . HidingFieldName ) ;
72+ }
73+
74+ [ Fact ]
75+ public void HidingJsonName_CaseInsensitive ( )
76+ {
77+ var json = @"{
78+ ""FIELD_NAME"": ""A field name""
79+ }" ;
80+
81+ var m = AssertReadJson < HelloRequest > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
82+ Assert . Equal ( "" , m . FieldName ) ;
83+ Assert . Equal ( "A field name" , m . HidingFieldName ) ;
84+ }
85+
86+ [ Fact ]
87+ public void JsonCustomizedName_CaseInsensitive ( )
88+ {
89+ var json = @"{
90+ ""JSON_CUSTOMIZED_NAME"": ""A field name""
91+ }" ;
92+
93+ var m = AssertReadJson < HelloRequest > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
94+ Assert . Equal ( "A field name" , m . FieldName ) ;
95+ }
96+
6397 [ Fact ]
6498 public void ReadObjectProperties ( )
6599 {
@@ -439,6 +473,23 @@ public void MapMessages()
439473 AssertReadJson < HelloRequest > ( json ) ;
440474 }
441475
476+ [ Fact ]
477+ public void MapMessages_CaseInsensitive ( )
478+ {
479+ var json = @"{
480+ ""mapMessage"": {
481+ ""name1"": {
482+ ""SUBFIELD"": ""value1""
483+ },
484+ ""name2"": {
485+ ""SUBFIELD"": ""value2""
486+ }
487+ }
488+ }" ;
489+
490+ AssertReadJson < HelloRequest > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
491+ }
492+
442493 [ Fact ]
443494 public void MapKeyBool ( )
444495 {
@@ -452,6 +503,21 @@ public void MapKeyBool()
452503 AssertReadJson < HelloRequest > ( json ) ;
453504 }
454505
506+ [ Fact ]
507+ public void MapKeyBool_CaseInsensitive ( )
508+ {
509+ var json = @"{
510+ ""mapKeybool"": {
511+ ""TRUE"": ""value1"",
512+ ""FALSE"": ""value2""
513+ }
514+ }" ;
515+
516+ // Note: JSON property names here are keys in a dictionary, not fields. So FieldNamesCaseInsensitive doesn't apply.
517+ // The new serializer supports converting true/false to boolean keys while ignoring case.
518+ AssertReadJson < HelloRequest > ( json , serializeOld : false ) ;
519+ }
520+
455521 [ Fact ]
456522 public void MapKeyInt ( )
457523 {
@@ -475,6 +541,16 @@ public void OneOf_Success()
475541 AssertReadJson < HelloRequest > ( json ) ;
476542 }
477543
544+ [ Fact ]
545+ public void OneOf_CaseInsensitive_Success ( )
546+ {
547+ var json = @"{
548+ ""ONEOFNAME1"": ""test""
549+ }" ;
550+
551+ AssertReadJson < HelloRequest > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
552+ }
553+
478554 [ Fact ]
479555 public void OneOf_Failure ( )
480556 {
@@ -486,6 +562,17 @@ public void OneOf_Failure()
486562 AssertReadJsonError < HelloRequest > ( json , ex => Assert . Equal ( "Multiple values specified for oneof oneof_test" , ex . Message . TrimEnd ( '.' ) ) ) ;
487563 }
488564
565+ [ Fact ]
566+ public void OneOf_CaseInsensitive_Failure ( )
567+ {
568+ var json = @"{
569+ ""ONEOFNAME1"": ""test"",
570+ ""ONEOFNAME2"": ""test""
571+ }" ;
572+
573+ AssertReadJsonError < HelloRequest > ( json , ex => Assert . Equal ( "Multiple values specified for oneof oneof_test" , ex . Message . TrimEnd ( '.' ) ) , deserializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
574+ }
575+
489576 [ Fact ]
490577 public void NullableWrappers_NaN ( )
491578 {
@@ -529,7 +616,27 @@ public void NullableWrappers()
529616 ""bytesValue"": ""SGVsbG8gd29ybGQ=""
530617}" ;
531618
532- AssertReadJson < HelloRequest . Types . Wrappers > ( json ) ;
619+ var result = AssertReadJson < HelloRequest . Types . Wrappers > ( json ) ;
620+ Assert . Equal ( "A string" , result . StringValue ) ;
621+ }
622+
623+ [ Fact ]
624+ public void NullableWrappers_CaseInsensitive ( )
625+ {
626+ var json = @"{
627+ ""STRINGVALUE"": ""A string"",
628+ ""INT32VALUE"": 1,
629+ ""INT64VALUE"": ""2"",
630+ ""FLOATVALUE"": 1.2,
631+ ""DOUBLEVALUE"": 1.1,
632+ ""BOOLVALUE"": true,
633+ ""UINT32VALUE"": 3,
634+ ""UINT64VALUE"": ""4"",
635+ ""BYTESVALUE"": ""SGVsbG8gd29ybGQ=""
636+ }" ;
637+
638+ var result = AssertReadJson < HelloRequest . Types . Wrappers > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
639+ Assert . Equal ( "A string" , result . StringValue ) ;
533640 }
534641
535642 [ Fact ]
@@ -629,8 +736,19 @@ public void JsonNamePriority_JsonName()
629736 {
630737 var json = @"{""b"":10,""a"":20,""d"":30}" ;
631738
632- // TODO: Current Google.Protobuf version doesn't have fix. Update when available. 3.23.0 or later?
633- var m = AssertReadJson < Issue047349Message > ( json , serializeOld : false ) ;
739+ var m = AssertReadJson < Issue047349Message > ( json ) ;
740+
741+ Assert . Equal ( 10 , m . A ) ;
742+ Assert . Equal ( 20 , m . B ) ;
743+ Assert . Equal ( 30 , m . C ) ;
744+ }
745+
746+ [ Fact ]
747+ public void JsonNamePriority_CaseInsensitive_JsonName ( )
748+ {
749+ var json = @"{""B"":10,""A"":20,""D"":30}" ;
750+
751+ var m = AssertReadJson < Issue047349Message > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
634752
635753 Assert . Equal ( 10 , m . A ) ;
636754 Assert . Equal ( 20 , m . B ) ;
@@ -642,14 +760,44 @@ public void JsonNamePriority_FieldNameFallback()
642760 {
643761 var json = @"{""b"":10,""a"":20,""c"":30}" ;
644762
645- // TODO: Current Google.Protobuf version doesn't have fix. Update when available. 3.23.0 or later?
646- var m = AssertReadJson < Issue047349Message > ( json , serializeOld : false ) ;
763+ var m = AssertReadJson < Issue047349Message > ( json ) ;
647764
648765 Assert . Equal ( 10 , m . A ) ;
649766 Assert . Equal ( 20 , m . B ) ;
650767 Assert . Equal ( 30 , m . C ) ;
651768 }
652769
770+ [ Fact ]
771+ public void JsonNamePriority_CaseInsensitive_FieldNameFallback ( )
772+ {
773+ var json = @"{""B"":10,""A"":20,""C"":30}" ;
774+
775+ var m = AssertReadJson < Issue047349Message > ( json , serializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
776+
777+ Assert . Equal ( 10 , m . A ) ;
778+ Assert . Equal ( 20 , m . B ) ;
779+ Assert . Equal ( 30 , m . C ) ;
780+ }
781+
782+ [ Fact ]
783+ public void FieldNameCase_Success ( )
784+ {
785+ var json = @"{""a"":10,""A"":20}" ;
786+
787+ var m = AssertReadJson < FieldNameCaseMessage > ( json ) ;
788+
789+ Assert . Equal ( 10 , m . A ) ;
790+ Assert . Equal ( 20 , m . B ) ;
791+ }
792+
793+ [ Fact ]
794+ public void FieldNameCase_CaseInsensitive_Failure ( )
795+ {
796+ var json = @"{""a"":10,""A"":20}" ;
797+
798+ AssertReadJsonError < FieldNameCaseMessage > ( json , ex => Assert . Equal ( "The JSON property name for 'Transcoding.FieldNameCaseMessage.A' collides with another property." , ex . Message ) , deserializeOld : false , settings : new GrpcJsonSettings { PropertyNameCaseInsensitive = true } ) ;
799+ }
800+
653801 private TValue AssertReadJson < TValue > ( string value , GrpcJsonSettings ? settings = null , DescriptorRegistry ? descriptorRegistry = null , bool serializeOld = true ) where TValue : IMessage , new ( )
654802 {
655803 var typeRegistery = TypeRegistry . FromFiles (
0 commit comments