Closed NinoFloris closed 11 months ago
So if I understand correctly, a way to tell FSharp.STJ to ignore WhenWritingNull on F# types would do the trick?
Maybe we can add an alternative version of WithSkippableOptionFields
that takes an enum instead of a boolean:
type R = { x: int option }
// Equivalent to current default aka .WithSkippableOptionFields(false):
let fsOptions = JsonFSharpOptions().WithSkippableOptionFields(SkippableOptionFields.FromJsonSerializerOptions)
let o1 = fsOptions.ToJsonSerializerOptions()
JsonSerializer.Deserialize<R>("{}", o1) // --> ERROR
let o2 = fsOptions.ToJsonSerializerOptions(DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)
JsonSerializer.Deserialize<R>("{}", o2) // --> { x = None }
// Equivalent of current .WithSkippableOptionFields(true):
let fsOptions = JsonFSharpOptions().WithSkippableOptionFields(SkippableOptionFields.Always)
let o1 = fsOptions.ToJsonSerializerOptions()
JsonSerializer.Deserialize<R>("{}", o1) // --> { x = None }
let o2 = fsOptions.ToJsonSerializerOptions(DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)
JsonSerializer.Deserialize<R>("{}", o2) // --> { x = None }
// New option that I think would work for you:
let fsOptions = JsonFSharpOptions().WithSkippableOptionFields(SkippableOptionFields.Never)
let o1 = fsOptions.ToJsonSerializerOptions()
JsonSerializer.Deserialize<R>("{}", o1) // --> ERROR
let o2 = fsOptions.ToJsonSerializerOptions(DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)
JsonSerializer.Deserialize<R>("{}", o2) // --> ERROR
Thanks for thinking along, yeah the latter seems like what I want.
Have you tried running this part on 1.1.23 though?
type R = { x: int option }
let fsOptions = JsonFSharpOptions().WithSkippableOptionFields(false)
let o1 = fsOptions.ToJsonSerializerOptions()
JsonSerializer.Deserialize<R>("{}", o1) // --> ERROR ## Does not actually error ##
It seems something regressed beyond JsonIgnoreCondition.WhenWritingNull as well
That's odd, when I try your exact code, I get this:
System.Text.Json.JsonException: Missing field for record type Program+R: x
Ah I see, it's because we have an alias for option = voption
So the actual problem is the following, tested in a clean project this time.
type R = { x: int voption }
let fsOptions = JsonFSharpOptions().WithSkippableOptionFields(false)
let o1 = fsOptions.ToJsonSerializerOptions()
JsonSerializer.Deserialize<R>("{}", o1) // --> ERROR ## Does not actually error ##
Ah indeed, that's not good, it should be an error.
This issue was in fact not fixed.
Effectively what we want is the following (optionally while also having WhenWritingNull enabled for our C# code):
Skippable<DateTime option>
this means the property can either be skipped entirely or set to null.DateTime option
it should be possible to set it to null but not omit it.Since the breaking change the latter just deserializes the empty record "{}" without errors.
SkippableOptionFields does not seem to be what we're after here.