java - 将 Java/JSON Map 解码为 F# 对象

标签 java json f# map datacontract

我在将 Java/JSON 映射转换为可用的 F# 对象时遇到问题。

这是我的代码的核心:

member this.getMapFromRpcAsynchronously =
    Rpc.getJavaJSONMap (new Action<_>(this.fillObjectWithJSONMap))
    ()

member this.fillObjectWithJSONMap (returnedMap : JSONMap<string, int> option) = 
    let container = Option.get(returnedMap)
    let map = container.map
    for thing in map do
        this.myObject.add thing.key
        // do stuff with thing
    ()

我的 RPC 方法返回的 JSON 如下所示:

{"id":1, "result":
    {"map":
        {"Momentum":12, "Corporate":3, "Catalyst":1},
     "javaClass":"java.util.HashMap"}
}

我正在尝试将其映射到如下所示的 F# DataContract:

[<DataContract>]
type JSONMap<'T, 'S> = {
    [<DataMember>]
    mutable map : KeyValuePair<'T, 'S> array
    [<DataMember>]
    mutable javaClass : string
}

[<DataContract>]
type JSONSingleResult<'T> = {
    [<DataMember>]
    mutable javaClass: string
    [<DataMember>]
    mutable result: 'T
}

最后,执行实际 RPC 调用(上面的 Rpc.getJavaJSONMap)的 F# 方法如下所示:

let getJavaJSONMap (callbackUI : Action<_>) = 
    ClientRpc.getSingleRPCResult<JSONSingleResult<JSONMap<string, int>>, JSONMap<string, int>>
        "MyJavaRpcClass"
        "myJavaRpcMethod"
        "" // takes no parameters
        callbackUI
        (fun (x : option<JSONSingleResult<JSONMap<string, int>>>) ->
            match x.IsSome with
                | true -> Some(Option.get(x).result)
                | false -> None 
        )

在编译时我没有得到任何错误。我的 RPC 方法被调用,并返回一个结果(使用 Fiddler 查看实际调用和返回)。但是,F# 似乎无法将 JSON 匹配到我的 DataContract,因为最顶部的 returnedMap 始终为 null。

如有任何想法或建议,我们将不胜感激。谢谢。

最佳答案

这是我做的:

open System.Web.Script.Serialization   // from System.Web.Extensions assembly

let s = @"
    {""id"":1, ""result"": 
        {""map"": 
            {""Momentum"":12, ""Corporate"":3, ""Catalyst"":1}, 
         ""javaClass"":""java.util.HashMap""} 
    } 
    "

let jss = new JavaScriptSerializer()
let o = jss.DeserializeObject(s)

// DeserializeObject returns nested Dictionary<string,obj> objects, typed
// as 'obj'... so add a helper dynamic-question-mark operator
open System.Collections.Generic 
let (?) (o:obj) name : 'a = (o :?> Dictionary<string,obj>).[name] :?> 'a

printfn "id: %d" o?id
printfn "map: %A" (o?result?map 
                   |> Seq.map (fun (KeyValue(k:string,v)) -> k,v) 
                   |> Seq.toList)
// prints:
// id: 1
// map: [("Momentum", 12); ("Corporate", 3); ("Catalyst", 1)]

关于java - 将 Java/JSON Map 解码为 F# 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4206445/

相关文章:

java - Intellij IDEA构建 Artifact 没有复制js和css文件

java - Spring : Send automated email to member and admin after timer expires

json - 以正确的 JSON 格式将 ansible 任务的输出写入文件

java - 在java中从json数组生成Excel工作表报告

c# - 如何构建F#类型的业务规则?

f# - 命名 F# 中本身就是参数的函数参数

java - 多键、链接哈希

java - 应用程序关闭时如何保存textview?

javascript - 带有 for 循环的 Array Splice 有问题

exception-handling - Async.Catch 对 OperationCanceledException 不起作用