0

For the code below

type MyConverter =
    inherit JsonConverter<Datetime>()

    .....

type MyType = {
    [<JsonConverter(typeof<MyConverter>)>]
    date: DateTime
}

JsonSerializer.Deserialize("{\"date\": \"2020-10-20\"}", typeof<MyType>)

converter is not invoked. It gets invoked for the entire type if the attribute will be moved there, but not for the field.

Is this by design? Any chance to specify the converter for an exact field?

DaveShaw
  • 52,123
  • 16
  • 112
  • 141
dr11
  • 5,166
  • 11
  • 35
  • 77
  • System.Text.Json won't allow deserializing record types. Is this working for you? – Asti Mar 06 '20 at 21:02
  • `System.Text.Json` doesn't support deserialization of immutable types, see [JsonSerializer support for immutable classes and structs. #29895](https://github.com/dotnet/runtime/issues/29895). It also doesn't handle fields though I don't remember off the top of my head if f# records are implemented using properties or fields. See: [Ensure JSON serializer/deserializer can handle common F# types #29812](https://github.com/dotnet/runtime/issues/29812). – dbc Mar 06 '20 at 22:06
  • @dbc They're properties, but they're read-only. ;) – Asti Mar 07 '20 at 05:03
  • 1
    Perhaps you can try to add [] attribute to your record declarations. This changes the way the records are compiled - getters and setters on properties and default constructors, so the records behave more like classes. – Piotr Rodak Mar 13 '20 at 17:44

2 Answers2

0

There seems to be two ways of defining the record type to get this to work

[<CLIMutable>]
type MyType = {
    [<JsonConverter(typeof<MyConverter>)>]
    date: DateTime
}

or

[<Struct>]
type MyType = {
    [<JsonConverter(typeof<MyConverter>)>]
    mutable date: DateTime
}
0

After all discussions we decided to use a combination of such solutions:

  1. Use global converters similar to this

  2. Modify Record converter which would recognize JsonConverter attribute and use it to convert the field value

dr11
  • 5,166
  • 11
  • 35
  • 77