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.
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
).
EDIT:
Following @ruben-bartelink's advice, I used the proposed nuget (FsCodec.NewtonsoftJson
) instead of my own custom converter. The code is much simpler now that I don't have to worry about writing my own conversion. Additionally, I don't have to switch to System.Text.Json
.
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.Converters.Add(new OptionConverter());
var whoisResponses = JsonConvert.DeserializeObject<SharedSupport.Models.Whois.WhoisResponseV2[]>(
snsMessage.Message,
jsonSerializerSettings);