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

ASP.NET Core操作MongoDB反序列化报JsonElement鉴别值未知错误

问题背景

正在开发集成MongoDB的ASP.NET Core项目,需要从HotelBookingDocument集合获取已预订酒店列表,相关实体定义如下:

public class HotelBookingDocument
{
    public string Id { get; set; }
    public HotelDocument Hotel { get; set; }
    // 其余代码省略
}

public class HotelDocument
{
    public List<RoomDocument> Rooms { get; set; }
    // 其余代码省略
}

public class RoomDocument
{
    public object SupplierReference { get; set; }
    // 其余代码省略
}
// 其余代码省略

已完成如下Bson序列化配置:

BsonClassMap.RegisterClassMap<HotelBookingDocument>(cm =>
{
  cm.AutoMap();
  cm.SetIgnoreExtraElements(true);
  cm.MapIdMember(c => c.Id)
    .SetSerializer(new StringSerializer(BsonType.ObjectId))
    .SetIgnoreIfDefault(true);
});

BsonClassMap.RegisterClassMap<RoomDocument>(cm =>
{
  cm.AutoMap();
});
BsonClassMap.RegisterClassMap<HotelDocument>(cm =>
{
  cm.AutoMap();
});

查询方法代码如下:

public async Task<List<HotelBookingDocument>> GetHotelsList(string transactionId)
{
  var hotels = await HotelBookingCollection.Find(x => x.TransactionId == transactionId).ToListAsync();   // 此处执行报错
  return hotels;
}

检查数据库存储时发现,部分文档的SupplierReference字段自动添加了"_t": "JsonElement"鉴别符,存储结构如下:

"SupplierReference": {
    "_t": "JsonElement"
},

字段存储截图:
SupplierReference字段数据库存储截图

执行列表查询时抛出如下异常:

System.FormatException: An error occurred while deserializing the Hotel property of class HotelBookingDocument: An error occurred while deserializing the Rooms property of class HotelBookingDocument+HotelDocument: An error occurred while deserializing the SupplierReference property of class HotelBookingDocument+RoomDocument: Unknown discriminator value 'JsonElement'.
---> System.FormatException: An error occurred while deserializing the Rooms property of class HotelBookingDocument+HotelDocument: An error occurred while deserializing the SupplierReference property of class HotelBookingDocument+RoomDocument: Unknown discriminator value 'JsonElement'.
---> System.FormatException: An error occurred while deserializing the SupplierReference property of class HotelBookingDocument+RoomDocument: Unknown discriminator value 'JsonElement'.
---> MongoDB.Bson.BsonSerializationException: Unknown discriminator value 'JsonElement'.
 at MongoDB.Bson.Serialization.BsonSerializer.LookupActualType(Type nominalType, BsonValue discriminator)
 at MongoDB.Bson.Serialization.Conventions.ObjectDiscriminatorConvention.GetActualType(IBsonReader bsonReader, Type nominalType)
 at MongoDB.Bson.Serialization.Serializers.ObjectSerializer.DeserializeDiscriminatedValue(BsonDeserializationContext context, BsonDeserializationArgs args)
 at MongoDB.Bson.Serialization.Serializers.ObjectSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
 at MongoDB.Bson.Serialization.Serializers.SerializerBase`1.MongoDB.Bson.Serialization.IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)...............

当前现象:按transactionId查询酒店预订列表时触发上述反序列化错误,但查询单条酒店预订文档时可正常返回第一条数据,无报错。

根因分析
  • _t是MongoDB C#驱动内置的类型鉴别符字段:当属性声明类型为object等非明确类型时,驱动序列化时会自动写入_t字段,存储值的实际运行时类型,用于反序列化时还原对应类型实例。
  • 数据库中出现"_t": "JsonElement"的原因:写入对应文档时,SupplierReference属性被赋值为System.Text.Json.JsonElement类型的值(常见场景为接口直接接收Json请求未做强类型映射、处理动态Json节点时直接将JsonElement传入该object属性),驱动序列化时自动将运行时类型名JsonElement作为鉴别符写入存储。
  • 反序列化报错原因:JsonElement是System.Text.Json的专属结构体,MongoDB C#驱动默认没有注册该类型的序列化器,也没有对应鉴别符的类型映射规则。查询列表时驱动会遍历所有匹配条件的文档,一旦读取到带"_t": "JsonElement"的文档,尝试根据鉴别符查找对应类型失败就会抛出异常。而单条查询默认返回匹配结果的第一条,如果第一条文档不存在该异常鉴别符,就不会触发报错,和观测到的现象完全一致。
修复方案
  • 优先方案:将SupplierReference属性的声明类型从object改为业务对应的强类型,从根源上避免object类型序列化自动生成类型鉴别符的问题,同时减少后续运行时类型转换的异常风险。
  • 动态类型适配方案:如果业务确实需要存储动态结构数据,给SupplierReference属性显式指定序列化器,统一用BsonDocument处理动态值,避免写入JsonElement相关的无效鉴别符,示例配置:
BsonClassMap.RegisterClassMap<RoomDocument>(cm =>
{
    cm.AutoMap();
    cm.MapMember(c => c.SupplierReference)
      .SetSerializer(new ObjectSerializer(BsonType.Document));
});
  • 存量数据修复:清理数据库中已存在的带"_t": "JsonElement"的脏数据,修正SupplierReference字段的存储结构,移除无效鉴别符,避免反序列化时匹配到未知类型。

内容的提问来源于stack exchange,提问作者hanushi-thana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:00:10