You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The serialization and deserialization of `FSharp.SystemTextJson` can be customized in two ways: using global options, and by adding attributes to specific types and properties.
4
+
3
5
<!-- doctoc --github docs/Customizing.md -->
4
6
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
5
7
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
6
8
7
-
-[How to apply customizations](#how-to-apply-customizations)
// --> (same format as without UnwrapFieldlessTags)
273
282
```
274
283
275
-
#### `UnwrapOption`
284
+
#####`UnwrapOption`
276
285
277
286
`JsonUnionEncoding.UnwrapOption` is enabled by default.
278
287
It causes the types `'T option` and `'T voption` (aka `ValueOption`) to be treated specially.
@@ -283,7 +292,7 @@ It causes the types `'T option` and `'T voption` (aka `ValueOption`) to be treat
283
292
Combined with the option `DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull` on `JsonSerializerOptions`, this can be used to represent optional fields: `Some` is a value that is present in the JSON object, and `None` is a value that is absent from the JSON object.
284
293
Note that the same effect can also be achieved more explicitly and more safely using [the `Skippable` type](#skippable).
285
294
286
-
#### `UnwrapSingleCaseUnions`
295
+
#####`UnwrapSingleCaseUnions`
287
296
288
297
`JsonUnionEncoding.UnwrapSingleCaseUnions` is enabled by default.
289
298
It causes unions that have a single case with a single field to be treated as simple "wrappers", and serialized as their single field's value.
This option sets the naming policy for union case names.
534
543
See [the System.Text.Json documentation about naming policies](https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-customize-properties).
When using the attribute, this option has enum type `JsonKnownNamingPolicy` instead.
545
554
546
-
## `unionFieldNamingPolicy`
555
+
###`unionFieldNamingPolicy`
547
556
548
557
This option sets the naming policy for union field names.
549
558
See [the System.Text.Json documentation about naming policies](https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-customize-properties).
Since the first release of `FSharp.SystemTextJson`, the base library `System.Text.Json` has added support for a number of F# types, including:
649
658
@@ -671,3 +680,98 @@ It also includes a few combined flags:
671
680
*`Collections`: lists, sets and maps.
672
681
*`Minimal`: All types not already fully supported by `System.Text.Json`. As of `FSharp.SystemTextJson` on .NET 6, this includes maps (for complex key types), unions and tuples (for tuples of more than 7 items).
673
682
*`All`: this is the default, `FSharp.SystemTextJson` handles all the types it supports.
683
+
684
+
## Attributes
685
+
686
+
### JsonFSharpConverter
687
+
688
+
The attribute `JsonFSharpConverterAttribute` on a type indicates that this type must be serialized using `FSharp.SystemTextJson`. See [Using attributes](Using.md#using-attributes) for applying it, and [How to apply options](#how-to-apply-options) for specializing global options on a type using this attribute.
689
+
690
+
### JsonName
691
+
692
+
`FSharp.SystemTextJson` supports the standard `JsonPropertyNameAttribute` to define the name of a property in JSON.
693
+
694
+
```fsharp
695
+
type Example =
696
+
{ [<JsonPropertyName "thisIsX">] x: string
697
+
y: string }
698
+
699
+
JsonSerializer.Serialize({ x = "Hello"; y = "world!" }, options)
700
+
// --> {"thisIsX":"Hello","y":"world!"}
701
+
```
702
+
703
+
However, it also includes its own attribute `JsonNameAttribute` which provides more functionality.
704
+
705
+
* It can be used exactly like `JsonPropertyNameAttribute`:
706
+
707
+
```fsharp
708
+
type Example =
709
+
{ [<JsonName "thisIsX">] x: string
710
+
y: string }
711
+
712
+
JsonSerializer.Serialize({ x = "Hello"; y = "world!" }, options)
713
+
// --> {"thisIsX":"Hello","y":"world!"}
714
+
```
715
+
716
+
* It can be used with multiple values. In this case, all the values are recognized as field names for deserialization. The first value is used for serialization.
JsonSerializer.Serialize({ x = "Hello"; y = "world!" }, options)
730
+
// --> {"thisIsX":"Hello","y":"world!"}
731
+
```
732
+
733
+
* It can be used on a discriminated union case to determine the tag of this case. In this situation, the value can be a string, an integer or a boolean.
734
+
735
+
```fsharp
736
+
type Example =
737
+
| [<JsonName 1>] One of int
738
+
| [<JsonName 2>] Two of string
739
+
740
+
JsonSerializer.Serialize(Two "hello", options)
741
+
// --> {"Case":2,"Fields":["hello"]}
742
+
```
743
+
744
+
Combined with `JsonUnionEncoding.InternalTag`, this is a way to encode the common pattern in JSON where the value of one field determines what other fields are allowed:
745
+
746
+
```fsharp
747
+
[<JsonFSharpConverter(JsonUnionEncoding.Default
748
+
||| JsonUnionEncoding.InternalTag
749
+
||| JsonUnionEncoding.NamedFields,
750
+
unionTagName = "isSuccess")>]
751
+
type MyResult<'t> =
752
+
| [<JsonName false>] Error of message: string
753
+
| [<JsonName true>] Ok of 't
754
+
755
+
JsonSerializer.Serialize(Ok {| x = 1; y = "hello" |})
756
+
// --> {"isSuccess":true,"x":1,"y":"hello"}
757
+
758
+
JsonSerializer.Serialize(Error "Failed to retrieve x")
759
+
// --> {"isSuccess":false,"message":"Failed to retrieve x"}
760
+
```
761
+
762
+
* Using the `Field` property, it can be used to indicate the name(s) of a discriminated case field.
763
+
764
+
```fsharp
765
+
[<JsonFSharpConverter(JsonUnionEncoding.Default
766
+
||| JsonUnionEncoding.InternalTag
767
+
||| JsonUnionEncoding.NamedFields,
768
+
unionTagName = "isSuccess")>]
769
+
type MyResult<'t> =
770
+
| [<JsonName false>]
771
+
[<JsonName("error", "errorMessage", Field = "message")]
772
+
Error of message: string
773
+
| [<JsonName true>] Ok of 't
774
+
775
+
JsonSerializer.Serialize(Error "Failed to retrieve x")
776
+
// --> {"isSuccess":false,"error":"Failed to retrieve x"}
0 commit comments