2015-04-17 88 views
0

我是编程新手,F#是我的第一语言。F#:JsonConvert.SerializeObject()多次保存相同的数据

我按照给我的建议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#交互式测试功能getFighterSummary和splitArrayIntoGroups。他们工作出色。

当我保存类型FighterSummary以JSON的记录,我看到这样的事情对于每个不同的战斗机:

{"[email protected]": "Alessio Sakara", 
"[email protected]": { 
    "Case": "Some", 
    "Fields": ["19-11-0 (1 NC)"] 
}, 
"[email protected]": { 
    "Case": "Some", 
    "Fields": [182.88] 
}, 
"[email protected]": { 
    "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' 属性没有被发现。 ---> System.Reflection.CustomAttributeFormatException: 未找到指定的'MemberSerialization'属性。

回答

1

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

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

+0

谢谢Daniel。我已更新我的问题,以包含有关反序列化JSON的问题。你是否也会就此问题向我提供建议? (即使我从每个字段中删除'mutable'关键字,问题仍然存在。) –

+0

我搞砸了一点,根本无法用或不用'[]'来重现您的问题,并且有或没有其他属性只是工作。我用这个代码:https://gist.github.com/DanielFabian/93bbec50678f5e26f4b0另外,我正在运行它Newtonsoft.Json 7.0.1-beta也许你有某种方式破碎的版本? –

+0

谢谢你的帮助,丹尼尔。事实证明,我犯了一个非常粗心的错误。一切正常,现在我已经修复它。再次感谢你! –