F#:JsonConvert.SerializeObject()多次保存相同的数据

时间:2015-04-17 11:14:02

标签: json f# json.net

我是编程新手,F#是我的第一语言。

我按照给我in this thread的建议使用了NewtonSoft.Json。以下是我的代码的一些相关部分:

    [<CLIMutable>]
    [<JsonObject(MemberSerialization=MemberSerialization.OptOut)>]
    type FighterSummary =
        { 
            mutable fighter: string; 
            mutable record: string option; 
            mutable reach: float option; 
            mutable stance: string option; 
        }

    let fighterFilesDir = @"G:\Fighter Pages"
    let fighterFiles = Directory.GetFiles(fighterFilesDir)
    let fighterGroups = splitArrayIntoGroups fighterFiles 50

    for group in fighterGroups do
        let fighterStats =   seq { 
                                    for file in group do
                                        let html = File.ReadAllText(file)
                                        let fighterOverview = getFighterSummary html
                                        printfn "Extracted %s's overview." (Path.GetFileNameWithoutExtension(file))
                                        yield fighterOverview
                                    } 
                                    |> Seq.toArray
        let fileName = Path.GetFileNameWithoutExtension(group.[0]) + " -- " + Path.GetFileNameWithoutExtension(group.[group.Count() - 1])
        let saveFilePath = @"G:\Fighter Data JSON Files\" + fileName + ".json"
        File.WriteAllText(saveFilePath, JsonConvert.SerializeObject(fighterStats))

我使用F#Interactive测试了函数getFighterSummary和splitArrayIntoGroups。他们工作出色。

当我将类型为FighterSummary的记录保存到JSON时,我会为每个不同的战斗机看到类似的内容:

{"fighter@": "Alessio Sakara",
"record@": {
    "Case": "Some",
    "Fields": ["19-11-0 (1 NC)"]
},
"reach@": {
    "Case": "Some",
    "Fields": [182.88]
},
"stance@": {
    "Case": "Some",
    "Fields": ["Orthodox"]
},
"fighter": "Alessio Sakara",
"record": {
    "Case": "Some",
    "Fields": ["19-11-0 (1 NC)"]
},
"reach": {
    "Case": "Some",
    "Fields": [182.88]
},
"stance": {
    "Case": "Some",
    "Fields": ["Orthodox"]}

关于每架战斗机的信息被保存两次 - 第一次在每个字段名称的末尾加上“@”,第二次没有。

我想要的是有关战斗机的信息只保存一次,而每个字段名称的末尾没有“@”。

我已经阅读了答案here,以回答遇到类似问题的人发布的问题。我已经尝试实施那里提供的建议,但它们没有用。

如果有人能帮我解决这个问题,我将不胜感激。谢谢。

编辑:

我也无法反序列化JSON。我跑的时候

JsonConvert.DeserializeObject<FighterSummary>(File.ReadAllText(@"G:\Fighter Data JSON Files\Fighters.json"))

我收到以下错误消息:

  

System.Reflection.CustomAttributeFormatException:   找不到指定的“MemberSerialization”属性。 ---&GT;   System.Reflection.CustomAttributeFormatException:   未找到“MemberSerialization”属性。

1 个答案:

答案 0 :(得分:1)

请注意,在您提到的帖子中,他们使用[<CliMutable>],但成员本身不是mutable。在查看代码时,我看不出为什么需要mutable(在F#中)。 mutable关键字允许使用在F#中很少使用的<-进行分配。 [<CliMutable>]就在那里,因此编译的代码是可变的,但在F#代码中它仍然是不可变的。

当您想要使用记录时,这有时很有用,例如使用反射。如果你只是[<CliMutable>]而不是在F#中制作mutable关键字,JSON.Net应该能够处理事情。