2013-04-29 2 views
4

Я пытаюсь десериализации некоторые очень простой JSON в F # с Newtonsoft.Json 5.0.4:Как я могу десериализовать Json с F #?

#if INTERACTIVE 
#r "C:/Users/OCatenacci/fshacks/CreateWeeklySWEEventsEmail/packages/Newtonsoft.Json.5.0.4/lib/net40/Newtonsoft.Json.dll" 
#endif 

open System 
open Newtonsoft.Json 

type meta() = class 
    member val count = 0 with get, set 
    end 

let testjson = """{ 
    "meta": { 
     "count": 15 
    } 
}""" 


let o = JsonConvert.DeserializeObject<meta>(testjson) 

мета всегда получает 0 в счете. Кстати, я был первоначально определение мета, как это:

type meta = { 
    count: int 
} 

И я изменил с помощью автоматического свойства, потому что я думал, что Newtonsoft.Json может быть не в состоянии правильно построить объект.

Я был бы удивлен, если моя версия F #/Windows имеет значение в этом случае, но только для полноты: я пытаюсь это с помощью F # 3.0 Repl (11.0.60315.1), и я запускаю на Win7 x64 (SP1).

+1

Считаете ли вы использование поставщика типа F # JSON? http://fsharp.github.io/FSharp.Data/library/JsonProvider.html – JonnyBoats

+0

@ JonnyBoats, что было бы хорошо, если бы поставщики типов поддерживались моно. Я хочу, чтобы это могло работать с моно. –

ответ

5

Попробуйте удалить самый большой набор фигурных скобок из вашего JSON. Прямо сейчас у вас есть объект, содержащий экземпляр meta. Это, вероятно, отбрасывает JSON.NET. Другими словами, я его прекрасно работать, используя:

let testjson = "{ 'count' : 15 }" 

[обновляемая база на комментарии]

В качестве альтернативы, вы можете сохранить JSON как есть, и обеспечить более сложный тип дерева в F #. Например:

type Foo = 
    { meta : Meta } 
and Meta = 
    { count : int } 
+0

Это хорошее предложение, но фактический json будет содержать внешнее имя, поэтому мне нужно выяснить, как его десериализировать. Я очень озадачен характером проблемы; как вы говорите, если формат json изменяется, он десериализуется отлично, поэтому он не кажется проблемой F #. –

+0

Все, что вам нужно сделать, это определить другой тип, который имеет «мета» в качестве члена. Затем десериализуем тип _that_. Что-то вроде 'type Foo = {meta: Meta} и Meta = {count: int}'. – pblasucci

+0

Вы знаете, что я задаюсь вопросом, связано ли это с механизмом вывода типа F # типа записи. Конечно, если бы это было так, вы бы подумали, что другой метод (автоматические члены) будет работать. –

0

С FSharp.Json библиотеке вы можете использовать только типы записей - не нужно больше определять классы. Структура записей, приведенных выше, достаточно просто:

type Foo = 
    { meta : Meta } 
and Meta = 
    { count : int } 

let testjson = """{"meta": {"count": 15}}""" 

open FSharp.Json 
let data = Json.deserialize<Foo> testjson 

Раскрытие: Я автор библиотеки FSharp.Json.