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

C#使用Newtonsoft反序列化MongoDB ObjectId出现转换错误如何解决

问题根因

你遇到的报错及自定义Converter未触发的核心原因有两个:

  1. document.ToJson()默认输出的是MongoDB扩展格式的非标准JSON,_id字段会输出为ObjectId("xxx")的语法,而不是标准JSON的字符串格式。Newtonsoft.Json在解析到第一个字符O时就会判定为非法JSON直接抛出异常,还未走到调用自定义Converter的逻辑,因此你写的MongoDataSerializer永远不会被触发。
  2. 你自定义的Converter是用于处理字符串转ObjectId的逻辑,但当前输入的JSON根本不符合标准结构,解析第一步就失败了。
最优解决方案(推荐,无需走JSON序列化中转)

完全不需要把BsonDocument转成JSON再反序列化,直接用MongoDB官方提供的Bson序列化方法即可,性能更高且不会出现格式兼容问题:

  1. 如果你最终需要_id以字符串形式存在,直接修改模型定义即可,无需自定义Converter:
public class BTMObj
{
    // 直接定义为string类型,MongoDB序列化器会自动将ObjectId转为字符串
    public string _id { get; set; }
    public string requestFormat { get; set; }
}
  1. 你甚至可以直接获取对应类型的集合,省去手动转换的步骤,GetMongoCollection方法可以简化为:
public List<T> GetMongoCollection<T>(string collectionName)
{
    try
    {
        var client = new MongoClient(Convert.ToString(ConfigurationManager.AppSettings["MONGO_CONNECTION"]));
        var database = client.GetDatabase(Convert.ToString(ConfigurationManager.AppSettings["MONGO_DB"]));
        // 直接获取对应类型的集合,无需中转BsonDocument和JSON
        var collection = database.GetCollection<T>(collectionName);
        return collection.Find(FilterDefinition<T>.Empty).ToList();
    }
    catch (Exception ex)
    {
        throw;
    }
}

如果需要保留原来遍历BsonDocument的逻辑,替换转换代码即可:

list.Add(BsonSerializer.Deserialize<T>(document));
兼容原有JSON转换逻辑的解决方案

如果你必须保留用Newtonsoft.Json反序列化的逻辑,需要先把ToJson的输出改为标准JSON格式:

  1. 调用ToJson时传入配置,输出严格模式的标准JSON:
var json = document.ToJson(new JsonWriterSettings 
{ 
    OutputMode = JsonOutputMode.Strict 
});

此时输出的JSON中_id会变为标准格式:"_id": {"$oid": "611cf42e1e4c89336b6fe2f0"}
2. 调整你的自定义Converter逻辑适配$oid结构,或者直接使用MongoDB官方为Newtonsoft.Json提供的ObjectIdConverter即可触发转换逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:06:03