Allow Int32 overflow in MongoDB C # 2.0 (new driver)
I have uint32 to serialize to MongoDB.
I used to do this using the following code from https://jira.mongodb.org/browse/CSHARP-252
public class AlwaysAllowUInt32OverflowConvention : ISerializationOptionsConvention
{
public IBsonSerializationOptions GetSerializationOptions(MemberInfo memberInfo)
{
Type type = null;
var fieldInfo = memberInfo as FieldInfo;
if (fieldInfo != null)
{
type = fieldInfo.FieldType;
}
var propertyInfo = memberInfo as PropertyInfo;
if (propertyInfo != null)
{
type = propertyInfo.PropertyType;
}
if (type == typeof(uint))
{
return new RepresentationSerializationOptions(BsonType.Int32) { AllowOverflow = true };
}
else
{
return null;
}
}
}
However, in the new library MongoDB ISerializationOptionsConvention
and RepresentationSerializationOptions
does not exist. I've looked and can't figure out how to register the ConventionPack (?) Standard framework to allow uint32 to overflow int32 in a new library.
How can I do this without adding the BsonRepresentation attribute to my POCO?
source to share
There are two ways that I can think you can do this. It is probably easiest to simply register a suitable serializer for the UInt32 type, for example:
var uint32Serializer = new UInt32Serializer(BsonType.Int32, new RepresentationConverter(true, true));
BsonSerializer.RegisterSerializer(uint32Serializer);
If you want to do it with conventions (which will only apply when class matching automatically), you can do this:
public class AlwaysAllowUInt32OverflowConvention : IMemberMapConvention
{
public string Name
{
get { return "AlwaysAllowUInt32Overflow"; }
}
public void Apply(BsonMemberMap memberMap)
{
if (memberMap.MemberType == typeof(UInt32))
{
var uint32Serializer = new UInt32Serializer(BsonType.Int32, new RepresentationConverter(true, true));
memberMap.SetSerializer(uint32Serializer);
}
}
}
And register the agreement like this:
var alwaysAllowUInt32OverflowConvention = new AlwaysAllowUInt32OverflowConvention();
var conventionPack = new ConventionPack();
conventionPack.Add(alwaysAllowUInt32OverflowConvention);
ConventionRegistry.Register("AlwaysAllowUInt32Overflow", conventionPack, t => true);
source to share
You can do it via IBsonSerializer
public class UInt32ToInt64Serializer : IBsonSerializer
{
public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
return (uint)context.Reader.ReadInt64();
}
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
context.Writer.WriteInt64((uint)value);
}
public Type ValueType { get { return typeof (uint); } }
}
and the serializer must be registered
BsonSerializer.RegisterSerializer(typeof(uint), new UInt32ToInt64Serializer());
source to share