2015-04-17 89 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

謝謝你的幫助,丹尼爾。事實證明,我犯了一個非常粗心的錯誤。一切正常,現在我已經修復它。再次感謝你! –