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

从MongoDB读取无类型数据遇未知鉴别器值错误,如何忽略鉴别器?

这个问题我之前也遇到过,本质是MongoDB C#驱动对_t鉴别器的默认处理逻辑和你的无类型读取需求冲突了。驱动看到_t字段就会尝试找到对应的.NET类型来反序列化,但你要么没定义这个类型,要么就是想直接以原始结构查看日志,不需要这个自动映射。给你几个实用的解决方案:

方案1:用BsonDocument读取并直接转为JSON(最适合日志查看场景)

因为你的核心需求是无类型展示日志,完全不需要把MongoDB文档反序列化成.NET对象,直接用BsonDocument读取,再转成JSON字符串传给前端是最直接的方式,能彻底避开鉴别器问题。修改代码如下:

// 获取BsonDocument类型的集合
var _collection = MongoDbFactory.GetDatabase(_connectionString).GetCollection<BsonDocument>(_collectionName);
var logDocuments = _collection.Find(filter).ToList();

// 使用MongoDB自带的序列化工具转成标准JSON,避免第三方序列化器的兼容性问题
var logJsonList = logDocuments.Select(doc => doc.ToJson(new JsonWriterSettings 
{ 
    Indent = true, // 可选,格式化JSON方便前端查看
    OutputMode = JsonOutputMode.Strict // 输出符合标准的JSON格式
})).ToList();

你之前用BsonDocument报错,大概率是误用了普通JSON序列化器(比如Newtonsoft.Json)来处理BsonDocument,换成MongoDB原生的ToJson方法就能完美解决。

方案2:配置序列化设置忽略鉴别器(如果需要反序列化为.NET对象)

如果你确实需要把日志反序列化为.NET对象做后端处理,可以给驱动配置序列化规则,让它忽略鉴别器字段:

// 创建自定义序列化设置:忽略鉴别器,同时忽略未知字段
var serializerSettings = new BsonSerializerSettings
{
    DiscriminatorHandling = DiscriminatorHandling.Ignore,
    IgnoreExtraElements = true
};

var _collection = MongoDbFactory.GetDatabase(_connectionString).GetCollection<object>(_collectionName);

// 读取文档并按自定义规则反序列化
var logs = _collection.Find(filter)
    .ToList()
    .Select(doc => BsonSerializer.Deserialize<object>(doc.ToBson(), serializerSettings))
    .ToList();

这个设置会告诉驱动不要解析_t字段,直接把整个文档当作无类型对象处理,不会再抛出"Unknown discriminator value"错误。

方案3:自定义日志模型类(最可控的结构化处理方式)

如果需要更结构化地处理日志,同时保留动态内容的灵活性,可以定义一个日志模型类,把包含动态数据的字段(比如routedata)声明为BsonDocument类型:

public class MongoLogEntry
{
    [BsonId]
    public ObjectId Id { get; set; }
    public DateTime Timestamp { get; set; }
    public string Level { get; set; }
    public string Thread { get; set; }
    public string Logger { get; set; }
    public string Message { get; set; }
    public BsonDocument ExceptionData { get; set; }
    public BsonDocument UserData { get; set; }
    public BsonDocument RouteData { get; set; } // 动态路由数据用BsonDocument存储
    public BsonDocument Data { get; set; }
}

然后用这个模型类读取日志:

var _collection = MongoDbFactory.GetDatabase(_connectionString).GetCollection<MongoLogEntry>(_collectionName);
var logs = _collection.Find(filter).ToList();

这种方式既保留了日志核心字段的结构化,又让动态内容以原始形式存在,不会触发驱动的鉴别器解析逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:06:27