.NET中MongoDB二进制数据序列化与反序列化的标准方案
.NET与MongoDB二进制数据序列化往返的解决方法
问题根源在于MongoDB .NET驱动的默认序列化逻辑:当你用IEnumerable<byte>作为属性类型时,驱动会把它序列化为BSON的Binary类型,但反序列化时,驱动无法自动将Binary实例化为IEnumerable<byte>的具体实现(比如List<byte>)——因为IEnumerable<byte>是接口,驱动不知道该创建哪个具体类,所以抛出类型不匹配的错误。
下面是两种惯用的解决方式:
方式一:改用具体的二进制数据类型(最简单推荐)
直接把IEnumerable<byte>替换成byte[]或者List<byte>,驱动对这两种具体类型的序列化反序列化有完美支持,能自动适配BSON的Binary类型,无需额外配置。
修改后的类代码:
public class File { // 改用byte[],也可以换成List<byte> public byte[] Data { get; set; } public string C { get; set; } public string D { get; set; } } public class X { public IEnumerable<File> Files { get; set; } public string A { get; set; } public string B { get; set; } }
这样存入和取出时都能正常序列化反序列化,不会出现类型错误。
方式二:自定义序列化器(保留IEnumerable时使用)
如果必须保留IEnumerable<byte>的属性类型,可以自定义一个序列化器,手动处理序列化和反序列化逻辑:
- 实现
IBsonSerializer<IEnumerable<byte>>接口:
public class IEnumerableByteSerializer : IBsonSerializer<IEnumerable<byte>> { public IEnumerable<byte> Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { // 把BSON Binary转成List<byte>,也可以换成其他IEnumerable实现 var binaryData = context.Reader.ReadBinaryData(); return binaryData.AsByteArray.ToList(); } public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, IEnumerable<byte> value) { // 把IEnumerable<byte>转成byte数组,再序列化为BSON Binary var byteArray = value.ToArray(); context.Writer.WriteBinaryData(new BsonBinaryData(byteArray)); } public Type ValueType => typeof(IEnumerable<byte>); object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { return Deserialize(context, args); } void IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) { Serialize(context, args, (IEnumerable<byte>)value); } }
- 注册这个序列化器到MongoDB驱动配置:
var clientSettings = MongoClientSettings.FromConnectionString("你的MongoDB连接字符串"); clientSettings.SerializerRegistry = BsonSerializerRegistry.Create(new BsonSerializerConfiguration { Serializers = { new IEnumerableByteSerializer() } }); var client = new MongoClient(clientSettings);
这样驱动就会用你自定义的逻辑处理IEnumerable<byte>类型的序列化和反序列化,解决类型不匹配的问题。
内容的提问来源于stack exchange,提问作者nbpeth
相关产品推荐
相关产品推荐

