I have found that just applying Ricardo Rodriguez' answer is not sufficient in some cases to properly serialize enum values to string into MongoDb:
// Set up MongoDB conventions
var pack = new ConventionPack
{
new EnumRepresentationConvention(BsonType.String)
};
ConventionRegistry.Register("EnumStringConvention", pack, t => true);
If your data structure involves enum values being boxed into objects, the MongoDb serialization will not use the set EnumRepresentationConvention
to serialize it.
Indeed, if you look at the implementation of MongoDb driver's ObjectSerializer, it will resolve the TypeCode
of the boxed value (Int32
for enum values), and use that type to store your enum value in the database. So boxed enum values end up being serialized as int
values. They will remain as int
values when being deserialized as well.
To change this, it's possible to write a custom ObjectSerializer
that will enforce the set EnumRepresentationConvention
if the boxed value is an enum. Something like this:
public class ObjectSerializer : MongoDB.Bson.Serialization.Serializers.ObjectSerializer
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
{
var bsonWriter = context.Writer;
if (value != null && value.GetType().IsEnum)
{
var conventions = ConventionRegistry.Lookup(value.GetType());
var enumRepresentationConvention = (EnumRepresentationConvention) conventions.Conventions.FirstOrDefault(convention => convention is EnumRepresentationConvention);
if (enumRepresentationConvention != null)
{
switch (enumRepresentationConvention.Representation)
{
case BsonType.String:
value = value.ToString();
bsonWriter.WriteString(value.ToString());
return;
}
}
}
base.Serialize(context, args, value);
}
}
and then set the custom serializer as the one to use for serializing objects:
BsonSerializer.RegisterSerializer(typeof(object), new ObjectSerializer());
Doing this will ensure boxed enum values will be stored as strings just like the unboxed ones.
Keep in mind however that when deserializing your document, the boxed value will remain a string. It will not be converted back to the original enum value. If you need to convert the string back to the original enum value, a discrimination field will likely have to be added in your document so the serializer can know what is the enum type to desrialize into.
One way to do it would be to store a bson document instead of just a string, into which the discrimination field (_t
) and a value field (_v
) would be used to store the enum type and its string value.