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
type RequireObjectPropertiesContractResolver() =
inherit DefaultContractResolver()
override __.CreateObjectContract(objectType: Type) =
let contract = base.CreateObjectContract objectType
contract.ItemRequired <- System.Nullable<Required>(Required.Always)
override __.CreateProperty(memberInfo: MemberInfo, memberSerialization: MemberSerialization) =
let property = base.CreateProperty(memberInfo, memberSerialization)
let isOption = property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() = typedefof<Option<_>>
property.Required <- Required.Default
property.NullValueHandling <- new System.Nullable<NullValueHandling>(NullValueHandling.Ignore)
let testRoundTrip<'T>(inputJson : string, settings : JsonSerializerSettings) =
printfn "\nTesting round-trip of %s with JSON string:\n %s" typeof<'T>.Name inputJson
let obj = JsonConvert.DeserializeObject<'T>(inputJson, settings)
let newJsonString = JsonConvert.SerializeObject(obj, settings)
printfn " Reserialized JSON string:\n %s" newJsonString
let test<'T>(inputObj : 'T, settings : JsonSerializerSettings) =
let inputJson = JsonConvert.SerializeObject(inputObj, settings)
testRoundTrip<'T>(inputJson, settings)
let settings = new JsonSerializerSettings()
settings.ContractResolver <- new RequireObjectPropertiesContractResolver()
test({FooType.id = 101; name = "John"; optional = Some 5}, settings)
test({FooType.id = 101; name = "John"; optional = None}, settings)
let badString = "{\"id\":101}"
testRoundTrip<FooType>(badString, settings)
raise (new InvalidOperationException("should not come here!"))
with | :? JsonException as ex ->
printfn "Caught expected exception: %s" ex.Message