App2015
App2015

Reputation: 993

JSON parsing collection of records

I've been struggling with this for long, I believe there's something wrong with my record design.

MY json looks like below. I posted this earlier as a part of another question but didn't get full answer especially for this part. Each record within the array is an object with a field name with data of type string.

JSON

[
    {
        "data": "/publication/a40a5e5c-98b3-45ae-d6a3-924b31d8712a/article/test;version=1521246543034"
    }, 
    {
        "data": "/publication/a40a5e5c-98b3-45ae-d6a3-924b31d8712a/book/test2;version=1520623346891"
    }, 
    {
        "data": "/publication/a40a5e5c-98b3-45ae-d6a3-924b31d8712a/catalog/test3;version=1520623346833"
    }
]

List.fs

open System.Runtime.Serialization

[<DataContract>]
type List= {
    [<field: DataMemberAttribute(Name="data") >]
    Data: string
}

Parsing JSON

let response = request.GetResponse() :?> HttpWebResponse
use reader = new StreamReader(response.GetResponseStream())
use memoryStream = new MemoryStream(ASCIIEncoding.Default.GetBytes(reader.ReadToEnd())) 
let jsonSerializer = DataContractJsonSerializer(typeof<List[]>)
let result = jsonSerializer.ReadObject(memoryStream) :?> List[]
Debug.WriteLine(sprintf "%A" result)

Actual Output - having nulls

[|
    {Data = null;}; 
    {Data = null;}; 
    {Data = null;}
|]

Expected Output

[|
    {Data = "/publication/a40a5e5c-98b3-45ae-d6a3-924b31d8712a/article/test;version=1521246543034";}; 
    {Data = "/publication/a40a5e5c-98b3-45ae-d6a3-924b31d8712a/book/test2;version=1520623346891";}
    {Data = "/publication/a40a5e5c-98b3-45ae-d6a3-924b31d8712a/catalog/test3;version=1520623346833";}
|]

Iteration

result 
 > Array.iter (fun x -> Console.WriteLine(x.Href))

Upvotes: 1

Views: 638

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243051

I suspect there must be something wrong with how you're reading the data. I tried to reproduce this and replaced the reading from a stream with reading from a string - so that I can test this - and the following works fine (in F# interactive version 14.0.23413.0):

#r "System.Runtime.Serialization"
open System.IO
open System.Text
open System.Runtime.Serialization
open System.Runtime.Serialization.Json

[<DataContract>]
type List= {
    [<field: DataMemberAttribute(Name="data") >]
    Data: string
}

let reader = new StringReader("""[
    { "data": "/publication/a40a5e5c/article/test;version=1521246543034" }, 
    { "data": "/publication/a40a5e5c/book/test2;version=1520623346891" }, 
    { "data": "/publication/a40a5e5c/catalog/test3;version=1520623346833" } ]""")

let memoryStream = new MemoryStream(ASCIIEncoding.Default.GetBytes(reader.ReadToEnd())) 
let jsonSerializer = DataContractJsonSerializer(typeof<List[]>)
let result = jsonSerializer.ReadObject(memoryStream) :?> List[]
result

Can you check that your input JSON is actually the one you shared here? To do that, see what reader.ReadToEnd() returns before calling GetBytes - I suspect there must be something wrong there, because the rest of the code works fine for me.

Upvotes: 2

Related Questions