open System.Collections.Generic
open System.Runtime.Serialization.Formatters
open System.ComponentModel.DataAnnotations
open System.Globalization
open Newtonsoft.Json.Linq
open Newtonsoft.Json.Converters
open Newtonsoft.Json.Serialization
open System.Text.Json.Serialization
open FSharp.System.Text.Json
type JsonConverterFactoryDecorator (innerConverter : JsonConverterFactory) =
inherit JsonConverterFactory ()
member private this.innerConverter = match innerConverter with | null -> nullArg "innerConverter" | _ -> innerConverter
override this.CanConvert(t) = innerConverter.CanConvert(t)
override this.CreateConverter(typeToConvert, options) = innerConverter.CreateConverter(typeToConvert, options)
type OptOutJsonConverterFactoryDecorator<'T when 'T :> System.Attribute> (innerConverter : JsonConverterFactory) =
inherit JsonConverterFactoryDecorator (innerConverter)
override this.CanConvert(t) = base.CanConvert(t) && not (t.IsDefined(typeof<'T>, true))
type JsonFSharpConverterOptOutAttribute () =
inherit System.Attribute()
type OptOutJsonFSharpConverter () =
inherit OptOutJsonConverterFactoryDecorator<JsonFSharpConverterOptOutAttribute>(new JsonFSharpConverter())
let options = JsonSerializerOptions()
options.Converters.Add(OptOutJsonFSharpConverter())
let PrintTypeData(aType : System.Type) =
printfn "\nData for type %s:" aType.Name
printfn " Fields of %s:" aType.Name
for f in aType.GetFields( BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.FlattenHierarchy ) do
printf " Field: %s" f.Name
for a in f.GetCustomAttributes(true) do
printf ", Attribute %O" a
printfn " Properties of %s:" aType.Name
for p in aType.GetProperties( BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.FlattenHierarchy ) do
printf " Property: %s" p.Name
for a in p.GetCustomAttributes(true) do
printf ", Attribute %O" a
printfn " Methods of %s:" aType.Name
for m in aType.GetMethods( BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance ||| BindingFlags.FlattenHierarchy ) do
printf " Method: %s" m.Name
for a in m.GetCustomAttributes(true) do
printf ", Attribute %O" a
let isOfType<'T> (x: obj) = x :? 'T
let PrintInferfaceMap(aType : System.Type, iType : System.Type) =
printfn "Printing mapping of interface %O to type %O" iType.Name aType.Name
let map = aType.GetInterfaceMap(iType)
for (iMethod, rMethod) in Seq.zip map.InterfaceMethods map.TargetMethods do
printfn " %O maps to %O" iMethod rMethod
type AClass(name : string) =
[<JsonProperty>] member this.id = this.Name
[<JsonProperty>] member this.id = this.Name
let aRec = {Name = "John"}
PrintInferfaceMap(typeof<ARec>, typeof<IRecord>)
PrintInferfaceMap(typeof<AClass>, typeof<IRecord>)
let json = JsonConvert.SerializeObject aRec
printfn "\nResult using JsonConvert.SerializeObject():\n%s" json
let aType = aRec.GetType()
PrintTypeData(typedefof<IRecord>)
printfn "aRec.Name: %s" aRec.Name
printfn "aRec.id: %s" (aRec :> IRecord).id