Десериализация JSON - PullRequest
       2

Десериализация JSON

1 голос
/ 07 июля 2011

Я пытаюсь десериализовать относительную простую строку JSON, которая выглядит следующим образом:

[{
    "FacebookID": "00000000000000",
    "Items": [{
        "BillID": "75a9ca7b-3b79-4db0-9867-83b2f66021d2",
        "FacebookID": "0000000000",
        "Description": "Some description",
        "Amount": 5000,
        "Accepted": false
    }]
}, {
    "FacebookID": "00000000000000",
    "Items": [{
        "BillID": "cec0a6d2-1db9-4a12-ae43-f61c6c69f0a6",
        "FacebookID": "0000000000",
        "Description": "Some description",
        "Amount": 3250,
        "Accepted": false
    }, {
        "BillID": "aaf51bb3-4ae6-48b5-aeb6-9c4d42fd4d2a",
        "FacebookID": "0000000000",
        "Description": "Some more..",
        "Amount": 100,
        "Accepted": false
    }]
}, {
    "FacebookID": "0000000000",
    "Items": [{
        "BillID": "2124cbc4-2a48-4ba4-a179-31d4191aab6a",
        "FacebookID": "0000000000",
        "Description": "even more..",
        "Amount": 300,
        "Accepted": false
    }]
}]

ничего необычного, как вы видите ... за исключением массива Items, но это не должно быть проблемой.

Если мы затем создадим несколько типов, соответствующих json-строке, и функцию, которая десериализует строку и отобразит ее в типах, мы получим что-то вроде:

[<DataContract>]
type Item = 
  { [<field: DataMember(Name = "BillID")>]
    BillID : string
    [<field: DataMember(Name = "FacebookID")>]
    FacebookID : string
    [<field: DataMember(Name = "Description")>]
    Description : string
    [<field: DataMember(Name = "Amount")>]
    Amount : int
    [<field: DataMember(Name = "Accepted")>]
    Accepted : bool }

[<DataContract>]
type Basic = 
  { [<field: DataMember(Name = "FacebookID")>]
    FacebookID : string 
    [<field: DataMember(Name = "Items")>]
    Items : Item array }

// My function to deserialize the json string, and map it to the given type.
let deserializeJson<'a> (s:string) =
  use ms = new MemoryStream(ASCIIEncoding.Default.GetBytes s)
  let serialize = DataContractSerializer(typeof<'a>)
  serialize.ReadObject ms :?> 'a

let get (url:string) =
  use web = new WebClient()
  web.DownloadString url

// Returns the JSON string
let result = deserializeJson<Basic array> <| get "http://some.com/blabla"

Вместо выполнения своей работы он просто выдает следующее исключение при попытке десериализации строки:

Необработанное исключение: System.Runtime.Serialization.SerializationException: произошла ошибка десериализацииобъект типа System.Collections.Generic.IList`1 [[Program + Basic, ConsoleApplication1, версия = 0.0.0.0, культура = нейтральная, PublicKe yToken = нулевая]].Данные на корневом уровне неверны.Строка 1, позиция 1.

Я что-то упустил?- JSON-строка совершенно корректна ...

1 Ответ

2 голосов
/ 07 июля 2011

Используемый вами сериализатор предназначен для XML, который вы хотите использовать DataContractJsonSerializer .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...