簡體   English   中英

如何使用Servicestack JSON序列化的F#Union類型?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM