Skip to content

Instantly share code, notes, and snippets.

@wegry
Created November 13, 2018 09:59
Show Gist options
  • Save wegry/05a63b8101d43ce858ab3c1a18cb5f7a to your computer and use it in GitHub Desktop.
Save wegry/05a63b8101d43ce858ab3c1a18cb5f7a to your computer and use it in GitHub Desktop.
Use Option<T> instead of null with Json.NET and F#
open Microsoft.FSharp.Reflection
open Newtonsoft.Json
open System
/// F# options-converter
type OptionConverter() =
inherit JsonConverter()
override __.CanConvert t = t.IsGenericType && typedefof<option<_>>.Equals(t.GetGenericTypeDefinition())
override __.WriteJson(writer, value, serializer) =
let value =
if isNull value then null
else
let _, fields = FSharpValue.GetUnionFields(value, value.GetType())
fields.[0]
serializer.Serialize(writer, value)
override __.ReadJson(reader, t, _, serializer) =
let innerType = t.GetGenericArguments().[0]
let innerType =
if innerType.IsValueType then typedefof<Nullable<_>>.MakeGenericType([| innerType |])
else innerType
let value = serializer.Deserialize(reader, innerType)
let cases = FSharpType.GetUnionCases t
if isNull value then FSharpValue.MakeUnion(cases.[0], [||])
else FSharpValue.MakeUnion(cases.[1], [| value |])
type ToStringJsonConverter() =
inherit JsonConverter()
override __.CanConvert _ = true
override __.WriteJson(writer : JsonWriter, value : obj, _ : JsonSerializer) : unit =
writer.WriteValue(value.ToString())
override __.CanRead = false
override __.ReadJson(_ : JsonReader, _ : Type, _ : obj, _ : JsonSerializer) : obj =
raise (NotImplementedException())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment