![](/img/trans.png)
[英]F#: How to deserialize a private discriminated union with Newtonsoft.Json?
[英]How to use F# Union types with Servicestack JSON serialization?
我想从框架中提出的问题太多了。 但只是想知道它是否有可能。 或者将会解决这个问题。
新版本的JSON.Net开始支持F#union类型。 解决这个问题的方法是什么,这意味着如果我使用servicestack.text,那么我如何展平联合类型以支持序列化。
这是两者的代码示例。
type Shape =
| Rectangle of width : float * length : float
| Circle of radius : float
| Empty
[<EntryPoint>]
let main argv =
// printfn "%A" argv
let shape1 = Rectangle(1.3, 10.0)
let json = JsonConvert.SerializeObject(shape1) //JSON.net
printfn "%A" json
// {
// "Case": "Rectangle",
// "Fields": [
// 1.3,
// 10.0
// ]
// }
let shape2 = JsonConvert.DeserializeObject<Shape>(json) //JSON.Net
printfn "%A" (shape2 = shape1) //true
let sJson = JsonSerializer.SerializeToString shape1 //SS.Text
printfn "%A" sJson
let sShape2 = JsonSerializer.DeserializeFromString sJson //SS.Text
printfn "%A" (sShape2 = shape1) //false
Console.Read() |> ignore
0 // return an integer exit code
使用servicestack进行反序列化返回false。 与JSON.net相比,生成的json字符串相当复杂。
如何为Union类型实现正确的序列化?
您必须为ServiceStack提供自定义序列化程序。 它想要这样,使用较小的Shape类型以简化:
open ServiceStack.Text
type Shape =
| Circle of float
| Empty
JsConfig<Shape>.SerializeFn
<- Func<_,_> (function
| Circle r -> sprintf "C %f" r
| Empty -> sprintf "E")
JsConfig<Shape>.DeSerializeFn
<- Func<_,_> (fun s ->
match s.Split [| |] with
| [| "C"; r |] -> Circle (float r)
| [| "E" |] -> Empty)
let shapes = [| Circle 8.0 |]
let json = JsonSerializer.SerializeToString(shapes)
let shapes1 = JsonSerializer.DeserializeFromString<Shape[]>(json)
let is_ok = shapes = shapes1
此代码在反序列化器中没有正确的异常传播:您希望处理match
不匹配,并且float
可能引发System.FormatException
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.