-
Type: Bug
-
Resolution: Duplicate
-
Priority: Major - P3
-
Affects Version/s: 1.0
-
Component/s: None
-
Environment:Windows 7
In my project I'm using a user defined struct named Identity as id's type. So I implemented a BsonSerializer and an IIDGenerator. Then I registered them using the lines below:
BsonSerializer.RegisterSerializer(typeof(Identity), new IdentitySerializer());
BsonSerializer.RegisterIdGenerator(typeof(Identity?), new IdentityGenerator());
Then I defined an Order class the uses the Identity type:
public class Order
{
public Identity? Id
public decimal Amount { get; set; }
}
If I save a new Order into a collection, everything run well.
But when I want to save an existing Order an ArgumentException is being thrown with this message: ".NET type MongoDriverBug.Identity cannot be mapped to a BsonValue"
So I did some debug and found that the exception was thrown by the method below:
public static BsonValue MapToBsonValue(object value) {
BsonValue bsonValue;
if (TryMapToBsonValue(value, out bsonValue))
var message = string.Format(".NET type {0} cannot be mapped to a BsonValue", value.GetType().FullName);
throw new ArgumentException(message);
}
I added some lines into the method to workaround the problem. The workaround tries to find a serializer for the value's type and if a serializer does exist, then it uses the serializer to convert the value to a valid BsonValue.
public static BsonValue MapToBsonValue(object value) {
BsonValue bsonValue;
if (TryMapToBsonValue(value, out bsonValue)) { return bsonValue; }
// ---------------------------------------------------------
// WORKAROUND START
var type = value.GetType();
var serializer = BsonSerializer.LookupSerializer(type);
if (serializer != null)
{
using (var stream = new MemoryStream())
{
using (var writer = BsonWriter.Create(stream))
{
writer.WriteStartDocument();
writer.WriteName("x");
serializer.Serialize(writer, type, value, null);
writer.WriteEndDocument();
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
using (var reader = BsonReader.Create(stream))
{ reader.ReadStartDocument(); reader.ReadName(); return BsonValue.ReadFrom(reader); } }
}
}
// WORKAROUND END
// ---------------------------------------------------------
var message = string.Format(".NET type
{0} cannot be mapped to a BsonValue", value.GetType().FullName);
throw new ArgumentException(message);
}