Is there any way to force parsing of only non-empty string fields of a record type in F# using Newtonsoft.Json?
#r """Newtonsoft.Json.dll"""
open Newtonsoft.Json
type Customer = {
Name: string
Email: string
ContactPhoneNo: string
}
// one or more fields can be empty
let customer = {
Name = ""
Email = "ca@gmail.com"
ContactPhoneNo = "+123456789"
}
let serializedCustomer =
JsonConvert.SerializeObject(customer)
// this parses correctly with the Name field set as ""
// But as the name field is empty, it should not parse it
let deserializedCustomer =
JsonConvert.DeserializeObject<Customer>(serializedCustomer)
You might want to consider using Newtonsoft's schema support for this, which is in a separate package called Newtonsoft.Json.Schema
. You can specify many different kinds of constraints using annotations. For example, to disallow blank names, you can use MinLength
:
open System.ComponentModel.DataAnnotations
type Customer = {
[<MinLength(1)>]
Name: string
Email: string
ContactPhoneNo: string
}
Once you've annotated your type, you can generate a schema:
let generator = JSchemaGenerator()
let schema = generator.Generate(typeof<Customer>)
Then use it to validate the serialized JSON:
let jsonCustomer = JObject.Parse(serializedCustomer)
let isValid = jsonCustomer.IsValid(schema)
If you want to skip the overhead of first loading JSON into a JObject
in order to validate it, you can use a JSchemaValidatingReader
instead:
use strReader = new System.IO.StringReader(serializedCustomer)
use txtReader = new JsonTextReader(strReader)
use vldReader = new JSchemaValidatingReader(txtReader, Schema = schema)
let messages = ResizeArray()
vldReader.ValidationEventHandler.Add(fun args -> messages.Add(args.Message))
let serializer = JsonSerializer()
let deserializedCustomer = serializer.Deserialize<Customer>(vldReader)
printfn "%A" deserializedCustomer
let isValid = (messages.Count = 0)
printfn "%A" isValid
See this documentation for details.