I have a uint32 to serialize to MongoDB.
I used to be able 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 MongoDB library the ISerializationOptionsConvention
and RepresentationSerializationOptions
do not exist. I've had a look and cannot see how to register a default ConventionPack (?) for allowing uint32 to overflow int32 on the new library.
How can I do this without adding a BsonRepresentation attribute to my POCO?
There are two ways I can think of that you can do this. Probably the easiest is to simply register a suitably configured serializer for type UInt32, like this:
var uint32Serializer = new UInt32Serializer(BsonType.Int32, new RepresentationConverter(true, true));
BsonSerializer.RegisterSerializer(uint32Serializer);
If you wanted to do it using conventions (which would only apply when mapping classes automatically), you could 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 convention like this:
var alwaysAllowUInt32OverflowConvention = new AlwaysAllowUInt32OverflowConvention();
var conventionPack = new ConventionPack();
conventionPack.Add(alwaysAllowUInt32OverflowConvention);
ConventionRegistry.Register("AlwaysAllowUInt32Overflow", conventionPack, t => true);
You can do it through 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 serializer should be registered
BsonSerializer.RegisterSerializer(typeof(uint), new UInt32ToInt64Serializer());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With