使用FsPickler

时间:2017-01-10 21:27:30

标签: json serialization f#

是否可以使用FsPickler序列化F#中的可选值,以便:

  • 当值为Some()时,包含的值是序列化的
  • 当它为None时,它根本没有被序列化?

使用以下示例代码:

type Person = { name: string; age: int option }

let data = [
  { name = "Helena"; age = Some(24) };
  { name = "Peter"; age = None }
] 

let jsonSerializer = FsPickler.CreateJsonSerializer(true, true)
let streamWriter = new StreamWriter(@"C:\output.json")
let out = jsonSerializer.SerializeSequence(streamWriter, data)

output.json文件包含以下JSON:

[
  {
    "name": "Helena",
    "age": {
      "Some": 24
    }
  },
  {
    "name": "Peter",
    "age": null
  }
]

但我希望JSON文件的内容看起来像这样:

[
  {
    "name": "Helena",
    "age": 24
  },
  {
    "name": "Peter"
  }
]

我使用的是FsPickler.Json v3.2.0和Newtonsoft.Json v9.0.1。

更新(2017年1月11日):在下面的答案中使用Stuart链接的要点中的脚本,我得到了这样的工作:

let obj = { name = "Peter"; age = None }
let stringWriter = new StringWriter()
let jsonSerializer = new JsonSerializer()
jsonSerializer.Converters.Add(new IdiomaticDuConverter())
jsonSerializer.NullValueHandling <- NullValueHandling.Ignore
jsonSerializer.Serialize(stringWriter, obj)

3 个答案:

答案 0 :(得分:3)

使用Newtonsoft.Json,您可以使用gist here(信用卡:Isaac Abraham)为您提供您所追求的行为。

很有趣,就在你发布这篇文章的那一刻之前,我想看看FsPickler.Json中是否存在同样的东西,但是得不到任何结论。您可以使用在FsPickler中使用的TypeShape来使gist更清晰,但不确定FsPickler.Json是否可以为您提供开箱即用的功能。

答案 1 :(得分:2)

我是作者FsPickler,所以我想我会在类似的issue中重新发布回复。

不,管理序列化格式的形状超出了此库的design goals。虽然您可以使用pickler combinators来影响序列化类型的外观,但这只会带您到目前为止。

答案 2 :(得分:1)

使用FSharp.Json库可以很好地工作:

open FSharp.Json

type Person = { name: string; age: int option }

let data = [
  { name = "Helena"; age = Some(24) };
  { name = "Peter"; age = None }
]

let json = Json.serialize data

这会生成以下JSON:

[
  { "name": "Helena", "age": 24 },
  { "name": "Peter", "age": null }
]

如何序列化选项None是可配置的。以下是如何省略具有None值的选项成员,请注意config:

let config = JsonConfig.create(serializeNone=SerializeNone.Omit)
let json = Json.serializeEx config data

披露:我是FSharp.Json图书馆的作者。