open System.IO
type TestType =
| A = 0
| B = 1
type TestObjectB =
{
test : TestType option
}
let jsonSerializeToString obj =
use writer = new StringWriter()
let ser = new Newtonsoft.Json.JsonSerializer()
ser.Formatting <- Newtonsoft.Json.Formatting.Indented
ser.Serialize(writer,obj)
writer.ToString()
let jsonDeserializeFromString str =
Newtonsoft.Json.JsonConvert.DeserializeObject<TestObjectB>(str)
let Test obj =
let str = jsonSerializeToString obj
let obj' = jsonDeserializeFromString str
obj'
[<EntryPoint>]
let main argv =
{ test = Some TestType.B } |> Test |> ignore
{ test = None } |> Test |> ignore
0
注意:如果需要序列化大量对象,则将它们流式传输到文件而不是内存中字符串,以避免OutOfMemoryException。像use writer = File.CreateText(filePath)
。
,
作为一个奖励问题,是否有一个可以解决问题的可行解决方案
枚举的惯用反序列化?
我在生产中使用了Microsoft.FsharpLu.Json包,发现它在“普通” javascript和惯用F#之间进行序列化和反序列化时效果很好。注意Microsoft.FsharpLu.Json
依赖于引擎盖下的Newtonsoft.Json
。
下面是您的类型和测试字符串的示例,使用Expecto进行测试。
namespace FsharpLuJsonTest
open Newtonsoft.Json
open Microsoft.FSharpLu.Json
open Expecto
open Expecto.Flip
// Setup for FSharpLu.Json
type JsonSettings =
static member settings =
let s = JsonSerializerSettings(
NullValueHandling = NullValueHandling.Ignore,MissingMemberHandling = MissingMemberHandling.Ignore)
s.Converters.Add(CompactUnionJsonConverter())
s
static member formatting = Formatting.None
type JsonSerializer = With<JsonSettings>
// Your example
type TestType =
| A = 0
| B = 1
type TestObjectA = { test : TestType }
type TestObjectB = { test : TestType option }
module Tests =
let x = """{"test":"A"}"""
[<Tests>]
let tests =
testList "Deserialization Tests" [
testCase "To TestObjectA" <| fun _ ->
JsonSerializer.deserialize x
|> Expect.equal "" { TestObjectA.test = TestType.A }
testCase "To TestObjectB" <| fun _ ->
JsonSerializer.deserialize x
|> Expect.equal "" { TestObjectB.test = Some TestType.A }
]
module Main =
[<EntryPoint>]
let main args =
runTestsInAssembly defaultConfig args
如您所见,FsharpLu.Json
以您喜欢的方式开箱即用地支持区分联合和选项类型。与Chiron之类的其他解决方案(允许更多自定义)相比,FsharpLu.Json
的灵活性较差,但我倾向于使用FsharpLu.Json
的自以为是的方法。
我还没有亲自使用过它,但是具有JsonUnionEncoding.ExternalTag
设置的新FSharp.SystemText.Json库应该与FsharpLu.Json
大致相同。该库在幕后使用Microsoft的新System.Text.Json
库,而不是Newtonsoft.Json
。
本文链接:https://www.f2er.com/3127307.html