2010-11-17 3 views
3

По какой-то причине, когда я сериализации типа (F #):DataContract/JsonSerializer '@' добавляется к именам переменных

type JsonKeyValuePair<'T, 'S> = { 
    [<DataMember>] 
    mutable key : 'T 
    [<DataMember>] 
    mutable value : 'S 
} 

let printJson() = 

    use stream = new MemoryStream() 
    use reader = new System.IO.StreamReader(stream) 

    let o = {key = "a"; value = 1 } 
    let jsonSerializer = Json.DataContractJsonSerializer(typeof<TestGrounds.JsonKeyValuePair<string, int>>) 

    jsonSerializer.WriteObject (stream , o) 
    stream.Seek(int64 0, SeekOrigin.Begin) |> ignore 

    printfn <| Printf.TextWriterFormat<unit>(reader.ReadToEnd()) 
    () 

Он генерирует строку:

{ "ключ @":» а», "значение @": 1}

и если я попытаюсь deserialze это без знака @:

let deserialize() = 
    let json = "{\"key\":\"b\",\"value\":2}" 
    let o = deserializeString<TestGrounds.JsonKeyValuePair<string, int>> json 
    () 

{«Тип контракта данных» TestGrounds.JsonKeyValuePair`2 [[System.String, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089], [System.Int32, mscorlib, Version = 4.0.0.0 , Culture = нейтрально, PublicKeyToken = b77a5c561934e089]]»не может быть десериализации, так как необходимые члены данных 'ключ @, значение @' не были найдены"}

Однако поставить @ обратно:.

let run2() = 
    let json = "{\"[email protected]\":\"b\",\"[email protected]\":2}" 
    let o = deserializeString<TestGrounds.JsonKeyValuePair<string, int>> json 
    () 

и мы все хороши. Насколько я знаю, спросите там нет ссылки на @ в Json Spec (http://www.json.org/) ...

+0

JSON действительно действителен, поэтому пока вы используете это внутренне (например, не ожидая, что скрипты JavaScript будут потреблять его, хотя они все равно могут быть), нет никаких проблем с конечными символами @. – cdhowie

ответ

5

F # генерирует поля называется [email protected] и [email protected] обратно свойства называется key и value. Попробуйте поместить атрибут DataContract на свой тип записи - без него сериализатор будет игнорировать атрибуты DataMember и, как представляется, просто выписывает каждое поле.

Смежные вопросы