@@ -177,8 +177,8 @@ module private Case =
177
177
else
178
178
i <- i + 1
179
179
180
- let casesByName ( fsOptions : JsonFSharpOptionsRecord ) ( cases : Case []) =
181
- if fsOptions.UnionTagCaseInsensitive then
180
+ let casesByName caseInsensitive ( cases : Case []) =
181
+ if caseInsensitive then
182
182
let dict = Dictionary( JsonNameComparer( StringComparer.OrdinalIgnoreCase))
183
183
for c in cases do
184
184
for name in c.Names do
@@ -221,7 +221,8 @@ module private Case =
221
221
match reader.TryGetInt32() with
222
222
| true , intName -> JsonName.Int intName
223
223
| false , _ -> failExpecting " union tag" & reader ty
224
- | JsonTokenType.String -> JsonName.String( reader.GetString())
224
+ | JsonTokenType.String
225
+ | JsonTokenType.PropertyName -> JsonName.String( reader.GetString())
225
226
| _ -> failExpecting " union tag" & reader ty
226
227
227
228
let isNamedFromReaderString ( case : Case ) ( reader : byref < Utf8JsonReader >) ( found : byref < ValueOption < _ >>) =
@@ -367,7 +368,7 @@ type JsonUnionConverter<'T>
367
368
else
368
369
ValueNone
369
370
370
- let casesByName = Case.casesByName fsOptions cases
371
+ let casesByName = Case.casesByName fsOptions.UnionTagCaseInsensitive cases
371
372
372
373
let getCaseByPropertyName ( reader : byref < Utf8JsonReader >) =
373
374
match Case.tryGetCaseByPropertyName casesByName cases & reader with
@@ -758,15 +759,23 @@ type JsonEnumLikeUnionConverter<'T> internal (options: JsonSerializerOptions, fs
758
759
759
760
let tagReader = FSharpValue.PreComputeUnionTagReader( typeof< 'T>, true )
760
761
761
- let cases =
762
+ let casesAsProperty =
762
763
let namingPolicy =
763
764
match fsOptions.UnionTagNamingPolicy with
764
765
| null -> options.PropertyNamingPolicy
765
766
| p -> p
766
767
FSharpType.GetUnionCases( typeof< 'T>, true )
767
768
|> Array.map ( Case.get namingPolicy fsOptions options)
768
769
769
- let casesByName = Case.casesByName fsOptions cases
770
+ let casesAsValue =
771
+ FSharpType.GetUnionCases( typeof< 'T>, true )
772
+ |> Array.map ( Case.get fsOptions.UnionTagNamingPolicy fsOptions options)
773
+
774
+ let casesByNameAsProperty =
775
+ Case.casesByName ( fsOptions.UnionTagCaseInsensitive || options.PropertyNameCaseInsensitive) casesAsProperty
776
+
777
+ let casesByNameAsValue =
778
+ Case.casesByName fsOptions.UnionTagCaseInsensitive casesAsValue
770
779
771
780
let nullValue =
772
781
tryGetNullValue fsOptions typeof< 'T> |> ValueOption.map ( fun x -> x :?> 'T)
@@ -783,20 +792,33 @@ type JsonEnumLikeUnionConverter<'T> internal (options: JsonSerializerOptions, fs
783
792
| JsonTokenType.Number
784
793
| JsonTokenType.True
785
794
| JsonTokenType.False ->
786
- let case = Case.getCaseByTagReader casesByName cases typeof< 'T> & reader
795
+ let case =
796
+ Case.getCaseByTagReader casesByNameAsValue casesAsValue typeof< 'T> & reader
787
797
case.Ctor [||] :?> 'T
788
798
| _ -> failExpecting " string" & reader typeToConvert
789
799
790
- override this.ReadAsPropertyName ( reader , typeToConvert , options ) =
791
- this.Read(& reader, typeToConvert, options)
800
+ override this.ReadAsPropertyName ( reader , typeToConvert , _options ) =
801
+ match reader.TokenType with
802
+ | JsonTokenType.Null ->
803
+ nullValue
804
+ |> ValueOption.defaultWith ( fun () -> failf " Union %s can't be deserialized from null" typeof< 'T>. FullName)
805
+ | JsonTokenType.PropertyName
806
+ | JsonTokenType.String
807
+ | JsonTokenType.Number
808
+ | JsonTokenType.True
809
+ | JsonTokenType.False ->
810
+ let case =
811
+ Case.getCaseByTagReader casesByNameAsProperty casesAsProperty typeof< 'T> & reader
812
+ case.Ctor [||] :?> 'T
813
+ | _ -> failExpecting " string" & reader typeToConvert
792
814
793
815
override this.Write ( writer , value , _options ) =
794
816
let tag = tagReader value
795
- Case.writeCaseNameAsValue writer cases [ tag]
817
+ Case.writeCaseNameAsValue writer casesAsValue [ tag]
796
818
797
819
override this.WriteAsPropertyName ( writer , value , _options ) =
798
820
let tag = tagReader value
799
- writer.WritePropertyName( cases [ tag]. NamesAsString[ 0 ])
821
+ writer.WritePropertyName( casesAsProperty [ tag]. NamesAsString[ 0 ])
800
822
801
823
type JsonUnionConverter ( fsOptions : JsonFSharpOptions ) =
802
824
inherit JsonConverterFactory()
0 commit comments