You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB反序列化报错:无法创建抽象类Test实例

问题描述

我定义了以下C#类:

public abstract class Test { }

public class ConcreteTest1: Test
{
    public string Foo {get; set; }
    //...
}

public class ConcreteTest2: Test
{
    public int AnInt { get; set; }
    //...
}

public class TestScript
{
    public ObjectId _id { get; set; } = new();
    public string PartNumber { get; set; }
    public IList<Test> Tests { get; set; } = [];
}

将TestScript存储到MongoDB时一切正常,但检索时抛出错误:

System.FormatException: 'An error occurred while deserializing the Tests property of class TestScript: Cannot create an instance of Test because it is an abstract class.'

MongoDB中的文档结构如下:

{
  "_id": {
    "$oid": "6780467598922ae42e13a832"
  },
  "PartNumber": "1234-12345-12",
  "Tests": [
    {  
      "_t": "ConcreteTest1",
      "Foo": "bar",
      ...
    },
    {
      "_t": "ConcreteTest2",
      "AnInt": 42
      ...
    }
  ]
}

检索代码:

var collection = db.GetCollection<TestScript>("TestScripts");

var testScript = await collection.Find(ts => ts.PartNumber == partNumber).SingleOrDefaultAsync(cancellationToken);
return testScript?.Tests ?? [];

如何让反序列化器识别子类类型?文档中已经包含_t类型标识,应该可以利用它。另外我是首次使用MongoDB,若有其他不当之处也请指出。

解决方案

MongoDB .NET驱动需要明确知道抽象基类的所有实现类型,才能正确解析_t类型标识完成反序列化,有两种常用配置方式:

方式一:使用特性标记已知类型

直接在抽象基类Test上添加[BsonKnownTypes]特性,列出所有子类:

[BsonKnownTypes(typeof(ConcreteTest1), typeof(ConcreteTest2))]
public abstract class Test { }

驱动在反序列化时会自动根据文档中的_t值匹配对应的子类。

方式二:代码配置类映射

如果不想在实体类中添加MongoDB专属特性,可以在程序初始化阶段(比如Program.cs启动时)配置类映射:

BsonClassMap.RegisterClassMap<Test>(cm =>
{
    cm.AutoMap();
    cm.AddKnownType(typeof(ConcreteTest1));
    cm.AddKnownType(typeof(ConcreteTest2));
});

这种方式更灵活,适合需要保持实体类纯净的场景。

额外注意点
  • 确保文档中的_t值和子类的类名完全一致(区分大小写),如果子类带有命名空间,可能需要在_t中包含命名空间,或者通过配置自定义类型名称规则。
  • 存储时驱动自动生成_t字段是默认启用了多态序列化,检索时必须配置已知类型才能正确解析。
  • 后续新增Test的子类时,需要同步更新已知类型配置(无论是特性还是代码映射),否则反序列化新子类实例会报错。

内容的提问来源于stack exchange,提问作者RoadieRich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:55:13