JamesNK / Newtonsoft.Json.Bson

Json.NET BSON adds support for reading and writing BSON to Json.NET
MIT License
55 stars 23 forks source link

Collections are written by BsonDataWriter as objects instead of array #9

Closed zorgoz closed 6 years ago

zorgoz commented 6 years ago

When using BsonDataWriter/BsonDateReader collections serialized can not be deserialized as the same type. It looks, that they are stored as objects.

Steps to reproduce:

void Main()
{
    var target = new T[] { new T{ V = 1 }, new T{ V = 2 }, new T{ V = 3 }};

    var s = new MemoryStream(100);

    JsonSerializer serializer = new JsonSerializer();
    serializer.Serialize(Console.Out, target); // As expected: [{"V":1},{"V":2},{"V":3}]

    using (var writer = new BsonDataWriter(s) { CloseOutput = false })
    {
        serializer.Serialize(writer, target);           
    }

    s.Position = 0;

    using (var reader = new BsonDataReader(s) { CloseInput = false })
    {
        // dynamic x = serializer.Deserialize(reader);
        // Console.WriteLine(JsonConvert.SerializeObject(x)); // Why?!: {"0":{"V":1},"1":{"V":2},"2":{"V":3}}

        var deserialized = serializer.Deserialize<T[]>(reader);
        /* EXCEPTION
        JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'T[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
        To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
        Path '0'.
        */
    }
}

class T { public int V { get; set; } }
JamesNK commented 6 years ago

Limitation of BSON

https://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_Bson_BsonReader_ReadRootValueAsArray.htm