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

含C# dynamic字段的模型写入MongoDB时抛出序列化异常

解决MongoDB序列化C# dynamic类型(JObject)的问题

问题核心

从Cosmos DB迁移到MongoDB时,使用InsertOneAsync()插入含dynamic属性的对象抛出序列化异常——原因是运行时dynamic实际为Newtonsoft.Json.Linq.JObject类型,而MongoDB默认序列化器未配置允许该类型序列化。

解决方案

方案1:替换dynamic为MongoDB原生BsonDocument类型

直接使用MongoDB的BsonDocument替代dynamic,这是最贴合MongoDB生态的方案,无需额外配置即可正常序列化。

修改模型类:

namespace Entities.Models
{
    [BsonIgnoreExtraElements]
    public class UPModel
    {
        [JsonProperty(PropertyName = "_id")]
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string BsonId { get; set; } = string.Empty;

        [BsonElement("resource")]
        public Resource Resource{ get; set; }

        [BsonElement("preference")]
        public Preference Preference { get; set; }
    }

    [BsonIgnoreExtraElements]
    public class Resource
    {
        [BsonElement("id")]
        public string Id { get; set; }

        [BsonElement("identifiers")]
        public BsonDocument Identifiers { get; set; }
    }

    [BsonIgnoreExtraElements]
    public class Preference
    {
        [BsonElement("id")]
        public string Id { get; set; }

        [BsonElement("value")]
        public BsonDocument Value { get; set; }
    }
}

如果原有数据是JObject类型,可直接转换为BsonDocument:

// 假设originalIdentifiers是JObject实例
resource.Identifiers = BsonDocument.Parse(originalIdentifiers.ToString());

方案2:注册JObject自定义序列化器

通过自定义序列化器,让MongoDB支持JObject类型的序列化/反序列化。

  1. 实现JObject序列化器:
public class JObjectBsonSerializer : IBsonSerializer<JObject>
{
    public Type ValueType => typeof(JObject);

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, JObject value)
    {
        var bsonDoc = BsonDocument.Parse(value.ToString());
        BsonDocumentSerializer.Instance.Serialize(context, args, bsonDoc);
    }

    public JObject Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var bsonDoc = BsonDocumentSerializer.Instance.Deserialize(context, args);
        return JObject.Parse(bsonDoc.ToJson());
    }
}
  1. 在MongoDB客户端初始化前注册序列化器:
BsonSerializer.RegisterSerializer(typeof(JObject), new JObjectBsonSerializer());

// 后续正常初始化客户端和集合
var client = new MongoClient("your_connection_string");
var database = client.GetDatabase("your_db");
var _collection = database.GetCollection<UPModel>("your_collection");

方案3:转换为Dictionary<string, object>

将JObject转换为Dictionary<string, object>,MongoDB默认支持该类型的序列化。

修改模型属性类型:

[BsonElement("identifiers")]
public Dictionary<string, object> Identifiers { get; set; }

[BsonElement("value")]
public Dictionary<string, object> Value { get; set; }

转换JObject为Dictionary:

// 假设originalValue是JObject实例
preference.Value = originalValue.ToObject<Dictionary<string, object>>();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:47:13