Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String can be null on serialization but throws on deserialization #144

Open
jannikbuschke opened this issue Dec 26, 2022 · 3 comments
Open

Comments

@jannikbuschke
Copy link

jannikbuschke commented Dec 26, 2022

    type A = { Value: string }

    let serialized = serializer.Serialize { Value = null }     // works => { "Value": null }
    let desieralized = serializer.Deserializ<A> ("""{"Value":null}""")     // throws

It seems this is by design and I am currently investigating why this is so. In general I think it would be nice to prevent all null assignments to strings, as the more proper way to implement a missing value would be string option.

Am I right that these defaults from the System.Text.Json https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/converters-how-to?pivots=dotnet-5-0#handle-null-values

By default, the serializer handles null values as follows:
For reference types and Nullable types:

  • It does not pass null to custom converters on serialization.
    ...

make the converters from this library never see null values for string and therefore do not fail, or does this lib totally ignores strings?

@jannikbuschke jannikbuschke changed the title String can be null on serialization but throws when deserialization String can be null on serialization but throws on deserialization Dec 26, 2022
@Tarmil
Copy link
Owner

Tarmil commented Jan 4, 2023

When serializing a field type that it doesn't explicitly handle, this library just hands it over to System.Text.Json. So that's indeed why null strings are serialized as null.

The deserializer is an input layer for the application, so it does data validation. Whereas the serializer is an output layer, it doesn't make much sense to do validation at this point.

@jannikbuschke
Copy link
Author

Interesting. I'm using your lib to store data in a postgresql database (https://jannikbuschke.de/blog/fsharp-marten if you are interested). So the data stays internal to my application and I need to make sure serialization and deserialization works bidirectionally.

My current solution is to add a custom converter for strings to prevent null strings to be serialized

type NullStringConverter() =
  inherit JsonConverter<string>()
  with
    override this.HandleNull = true
    override this.Read(reader, typeToConvert, options) = reader.GetString ()
    override this.Write(writer, value, options) =
      if value = null then
        raise (NotSupportedException ("Value null is not allowed for type String."))
      else
        writer.WriteStringValue value

Do you think there is a better approach and/or should this be documented? It doesn't seem that someone else stumbled upon this, but it could bite people in the future.

@Tarmil
Copy link
Owner

Tarmil commented Feb 12, 2023

I don't think there's anything better to do if you want to handle this within the serialization layer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants