【问题标题】:F#: JsonConvert.SerializeObject() saves the same data multiple timesF#:JsonConvert.SerializeObject() 多次保存相同的数据
【发布时间】:2015-04-17 11:14:01
【问题描述】:

我是编程新手,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: 未找到指定的“成员序列化”属性。 ---> System.Reflection.CustomAttributeFormatException: 找不到指定的“MemberSerialization”属性。

【问题讨论】:

    标签: json f# json.net


    【解决方案1】:

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

    这有时在您想使用记录时很有用,例如使用反射。如果您只是 [&lt;CliMutable&gt;] 而不是在 F# 中使用 mutable 关键字,那么 JSON.Net 应该能够处理这些事情。

    【讨论】:

    • 谢谢,丹尼尔。我已经更新了我的问题以包含与反序列化 JSON 有关的问题。你也愿意就这个问题给我建议吗? (即使我从每个字段中删除了“可变”关键字,问题仍然存在。)
    • 我有点搞砸了,无论有没有[&lt;CLIMutable&gt;],无论有没有其他属性,它都无法重现您的问题。我使用了这段代码:gist.github.com/DanielFabian/93bbec50678f5e26f4b0 另外,我正在运行它 Newtonsoft.Json 7.0.1-beta 也许你有某种损坏的版本??
    • 感谢您的帮助,丹尼尔。事实证明,我犯了一个非常粗心的错误。既然我已经修好了,一切都很好。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多