将 F# 可区分联合序列化为带有 Json.NET 的字符串



我正在尝试在序列化时从 F# 的区分联合到字符串的单向转换,而不是默认的"大小写":[值]"。能够再次反序列化值不是问题。也许可以用 Json.NET?

// Fsharp 4.1.0
open Newtonsoft.Json // 10.0.3
type HowLame =
| PrettyLame
| SuperLame
type Lame = {
    howLame: HowLame;
}
[<EntryPoint>]
let main argv =
    let lame = { howLame = PrettyLame }
    let ser = JsonConvert.SerializeObject(lame)
    // {"soLame":{"Case":"PrettyLame"}} by default
    printfn "%s" ser
    // Desired
    assert (ser = """{"soLame":"PrettyLame"}""")
    0 // return an integer exit code
创建自定义

Json.NET JsonConverter 并使用它来装饰可区分的联合("枚举样式"(足以使它按照我想要的方式工作。其中很大一部分是从 C# @Brian Rogers 的答案音译而来的 https://stackoverflow.com/a/22355712/1924257

open System
open Newtonsoft.Json // 10.0.3
open Newtonsoft.Json.Converters
type ToStringJsonConverter () =
    inherit JsonConverter()
    override this.CanConvert objectType = true;
    override this.WriteJson (writer: JsonWriter, value: obj, serializer: JsonSerializer): unit = 
        writer.WriteValue(value.ToString())
    override this.CanRead = false
    override this.ReadJson (reader: JsonReader, objectType: Type, existingValue: obj, serializer: JsonSerializer) : obj =
        raise (new NotImplementedException());
[<JsonConverter(typeof<ToStringJsonConverter>)>]
type HowLame =
| PrettyLame
| SuperLame
type Lame = {
    howLame: HowLame
}
[<EntryPoint>]
let main argv =
    let lame = { howLame = PrettyLame }
    let ser = JsonConvert.SerializeObject(lame)
    // {"howLame":"PrettyLame"}
    printfn "%s" ser
    0 // return an integer exit code

如果您愿意将 DU 设置为枚举(通过指定显式值,这可能是可以的,因为没有"有效负载"(,您可以使用标准StringEnumConverter

#r "../packages/Newtonsoft.Json/lib/net45/Newtonsoft.Json.dll"
open Newtonsoft.Json
type HowLame = PrettyLame=0 | SuperLame=1
type Lame = { howLame: HowLame; }
// in contrast to DUs, enums must be qualified, i.e. Enum.Value
let lame = { howLame = HowLame.PrettyLame }
let settings = JsonSerializerSettings()
settings.Converters.Add(Converters.StringEnumConverter())
let ser = JsonConvert.SerializeObject(lame, settings)
// val ser : string = "{"howLame":"PrettyLame"}"

相关内容

  • 没有找到相关文章

最新更新