F#JSON类型提供程序,不要序列化空值

时间:2018-05-03 17:00:43

标签: json f# f#-data

背景

我正在使用FSharp.Data JSON Type Provider,其示例包含可能具有不同属性的对象数组。这是一个说明性的例子:

return new Container(
      decoration: new BoxDecoration(
        image: new DecorationImage(
            image: new ExactAssetImage("images/barber.jpeg"),
            fit: BoxFit.cover
        )
      ),
      child: new SizedBox(
        height: 200.0,
        width: 200.0,
        child: new BackdropFilter(
          filter: new ui.ImageFilter.blur(
            sigmaX: 5.0,
            sigmaY: 5.0,
          ),
          child: new Center(
            child: new Text("Hi"),
          ),
        ),
      ),
    );
  }

JSON类型提供程序创建一个具有Optional Name和Optional Year属性的Input类型。这很有效。

问题

当我尝试将此实例传递给Web服务时,我会执行以下操作:

[<Literal>]
let sample = """
    { "input": [
        { "name": "Mickey" },
        { "year": 1928 }
       ] 
    }
"""
type InputTypes = JsonProvider< sample >

Web服务正在接收以下内容并阻塞空值。

InputTypes.Root(
    [|
        InputTypes.Input(Some("Mouse"), None)
        InputTypes.Input(None, Some(2028))
    |]
)

我尝试过什么

我发现这有效:

{
  "input": [
    {
      "name": "Mouse",
      "year": null
    },
    {
      "name": null,
      "year": 2028
    }
  ]
}

它发送:

InputTypes.Root(
    [|
        InputTypes.Input(JsonValue.Parse("""{ "name": "Mouse" }"""))
        InputTypes.Input(JsonValue.Parse("""{ "year": 2028 }"""))
    |]
)

然而,在我的真实项目中,结构更大,并且需要更多条件JSON字符串构建。它有点挫败了目的。

问题

  • 有没有办法让JSON Type Provider不能序列化null属性?
  • 有没有办法让JSON Type Provider不能序列化空数组?

作为比较点,Newtonsoft.JSON库具有NullValueHandling属性。

1 个答案:

答案 0 :(得分:2)

我不认为有一种简单的方法可以在F#数据中获取JSON格式以删除null字段 - 我认为该类型无法明确区分null和缺少什么。

您可以通过编写帮助函数来删除所有null字段来解决这个问题:

let rec dropNullFields = function
  | JsonValue.Record flds ->
      flds 
      |> Array.choose (fun (k, v) -> 
        if v = JsonValue.Null then None else
        Some(k, dropNullFields v) )
      |> JsonValue.Record
  | JsonValue.Array arr -> 
      arr |> Array.map dropNullFields |> JsonValue.Array
  | json -> json

现在,您可以执行以下操作并获得所需的结果:

let json = 
  InputTypes.Root(
      [|
          InputTypes.Input(Some("Mouse"), None)
          InputTypes.Input(None, Some(2028))
      |]
  )

json.JsonValue |> dropNullFields |> sprintf "%O"