Context:
one type has two representations: one in C# and one in F#. Value of the C# type gets serialized to json and then deserialized into a value of the F# type.
Is there a straightforward way to convert null
json properties to Option<>
F# values?
I'm facing a situation where null
C# DateTime? UpdatedDate
property gets serialized to json and then is expected to be deserialized into an FSharpOption<DateTime> UpdatedDate
value (F# type, C# code, long story...) which breaks the code.
My json looks like this:
{
"Property1": "1",
"UpdatedDate": null,
"Property2": "2"
}
I technically could deserialize my json to the C# type containing DateTime? UpdatedDate
and then map the resulting value to the F# type containing FSharpOption<DateTime> UpdatedDate
, but surely there must be a better way...
EDIT:
To deserialize json I'm using Newtonsoft's JsonConvert.DeserializeObject
and .NET 5 C# 9.
CodePudding user response:
OptionConverter
in the Newtonsoft.Json.FSharp package can handle this for you. Your code will look something like this:
let records =
JsonConvert.DeserializeObject<MyType[]>(
json,
[| OptionConverter() :> JsonConverter |])
CodePudding user response:
Ok, I figured it out thanks to the example @brianberns shared. Sample code:
public class DummyJsonConverter : JsonConverter<FSharpOption<DateTime>>
{
public override FSharpOption<DateTime> Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options) =>
FSharpOption<DateTime>.None;
public override void Write(
Utf8JsonWriter writer,
FSharpOption<DateTime> dateTimeValue,
JsonSerializerOptions options) =>
writer.WriteStringValue("");
}
Usage:
var serializerOptions = new JsonSerializerOptions();
serializerOptions.Converters.Add(new DummyJsonConverter());
var whoisResponses = JsonSerializer.Deserialize<SharedSupport.Models.Whois.WhoisResponseV2[]>(
snsMessage.Message,
serializerOptions);
The only caveat is that I replaced the Newtonsoft serializer with the System.Text.Json
serializer (JsonSerializer
).