Serialization of byte[]

129 views
Skip to first unread message

Stuart Harris

unread,
Jun 23, 2010, 12:33:23 PM6/23/10
to mongodb-csharp
Hi, I'm having problems with the bson serializer and properties of
type byte[]. It seems to try to calculate the size of each byte
individually. The following exception was thrown during serialization
of an object with a byte[] property (stack trace shortened):

System.ArgumentOutOfRangeException was unhandled by user code
Message=Specified argument was out of the range of valid values.
Parameter name: Type: System.Byte not recognized
Source=MongoDB
ParamName=Type: System.Byte not recognized
StackTrace:
at MongoDB.Bson.BsonWriter.TranslateToBsonType(Object obj) in D:
\Dev\mongodb-csharp\source\MongoDB\Bson\BsonWriter.cs:line 612
at MongoDB.Bson.BsonWriter.CalculateSize(Object obj) in D:\Dev
\mongodb-csharp\source\MongoDB\Bson\BsonWriter.cs:line 325
at MongoDB.Bson.BsonWriter.CalculateSizeObject(Object obj,
IEnumerable`1 propertys) in D:\Dev\mongodb-csharp\source\MongoDB\Bson
\BsonWriter.cs:line 485
at MongoDB.Bson.BsonWriter.CalculateSize(IEnumerable
enumerable) in D:\Dev\mongodb-csharp\source\MongoDB\Bson
\BsonWriter.cs:line 503
at MongoDB.Bson.BsonWriter.CalculateSize(Object obj) in D:\Dev
\mongodb-csharp\source\MongoDB\Bson\BsonWriter.cs:line 349
at MongoDB.Bson.BsonWriter.CalculateSizeObject(Object obj,
IEnumerable`1 propertys) in D:\Dev\mongodb-csharp\source\MongoDB\Bson
\BsonWriter.cs:line 485
at MongoDB.Bson.BsonWriter.CalculateSizeObject(Object obj) in D:
\Dev\mongodb-csharp\source\MongoDB\Bson\BsonWriter.cs:line 464
at MongoDB.Bson.BsonWriter.CalculateSize(Object obj) in D:\Dev
\mongodb-csharp\source\MongoDB\Bson\BsonWriter.cs:line 347
at MongoDB.Protocol.InsertMessage.ChunkMessage(BsonWriter
writer) in D:\Dev\mongodb-csharp\source\MongoDB\Protocol
\InsertMessage.cs:line 73
at MongoDB.Protocol.InsertMessage.Write(Stream stream) in D:\Dev
\mongodb-csharp\source\MongoDB\Protocol\InsertMessage.cs:line 56
at
MongoDB.Connections.Connection.SendMessageCore(IRequestMessage
message) in D:\Dev\mongodb-csharp\source\MongoDB\Connections
\Connection.cs:line 144
at MongoDB.Connections.Connection.SendMessage(IRequestMessage
message, String database) in D:\Dev\mongodb-csharp\source\MongoDB
\Connections\Connection.cs:line 128
at MongoDB.MongoCollection`1.Insert[TElement](IEnumerable`1
documents) in D:\Dev\mongodb-csharp\source\MongoDB
\MongoCollection_1.cs:line 333
at MongoDB.MongoCollection`1.Insert(Object document) in D:\Dev
\mongodb-csharp\source\MongoDB\MongoCollection_1.cs:line 283

So I thought that the following test would prove this:

public class ByteArrayObject
{
public byte[] A { get; set; }
}

[Test]
public void CanConvertByteArrayValue(){
var bytes = new byte[] { 1 };
var bson = Serialize(new Document("A", bytes));
var result = Deserialize<ByteArrayObject>(bson);

Assert.AreEqual(bytes, result.A);
}

But weirdly it succeeds on the serialization and fails on the de-
serialization with the following exception:

System.InvalidCastException : Unable to cast object of type
'MongoDB.Binary' to type 'System.Object[]'.
at
MongoDB.Configuration.Mapping.Model.CollectionMemberMap.SetValue(Object
instance, Object value) in CollectionMemberMap.cs: line 62
at
MongoDB.Serialization.Builders.ConcreteClassMapBuilder.AddProperty(String
name, Object value) in ConcreteClassMapBuilder.cs: line 33
at MongoDB.Serialization.BsonClassMapBuilder.EndProperty(Object
instance, String name, Object value) in BsonClassMapBuilder.cs: line
73
at MongoDB.Bson.BsonReader.ReadElement(Object instance) in
BsonReader.cs: line 119
at MongoDB.Bson.BsonReader.ReadElements(Object instance) in
BsonReader.cs: line 99
at MongoDB.Bson.BsonReader.ReadObject() in BsonReader.cs: line 76
at
MongoDB.UnitTests.Serialization.SerializationTestBase.Deserialize(String
base64) in SerializationTestBase.cs: line 23
at
MongoDB.UnitTests.Serialization.Builders.ValueConversionTests.CanConvertByteArrayValues()
in ValueConversionTests.cs: line 32

I hoped that I could find the problems and submit a patch, but it's
going to take me a while to get up to speed with the code. So in the
meantime, I'm posting this here in case someone gets there before me!

Cheers
Stu

Steve Wagner

unread,
Jun 23, 2010, 1:16:18 PM6/23/10
to mongodb...@googlegroups.com
This is because the BsonWriter writes byte[] as Binary(MongoDB-CSharp
type which maps to the coresponding BSON type) and so it also reads
that. The deserializer currently not convert it back while setting a
property.

You can make it work if you change you model to:

public class ByteArrayObject
{
public Binary A { get; set; }
}

The Binary type also supports direct conversion to and from byte[]. So

var bytes = new byte[100];
....
obj.A = bytes;

Should work.

I plan to add conversion to byte[] while setting the property soon.

-Steve

Sam Corder

unread,
Jun 23, 2010, 1:25:38 PM6/23/10
to mongodb...@googlegroups.com
Stu, would you mind filing a JIRA for this?

Stuart Harris

unread,
Jun 23, 2010, 4:32:36 PM6/23/10
to mongodb-csharp

Great - that works. Thanks guys.

I recorded it in Jira (http://jira.mongodb.org/browse/CSHARP-46).

Cheers
Stu
Reply all
Reply to author
Forward
0 new messages