ASP.NET Core 6含dynamic属性模型MongoDB序列化错误解决求助
解决方案:ASP.NET Core 6 + MongoDB.Driver 动态属性序列化错误修复
错误根源:通过Swagger提交请求时,ASP.NET Core的System.Text.Json会将JSON payload解析为JsonElement类型赋值给dynamic属性,但MongoDB驱动的ObjectSerializer默认不支持序列化JsonElement,导致抛出异常。以下是三种可行解决办法:
方法1:替换dynamic为MongoDB原生BsonDocument
直接使用MongoDB内置的BsonDocument类型存储动态数据,这是最贴合MongoDB设计的方案,无需额外序列化配置:
// 修改模型类 public class Servicio { // 其他属性... public BsonDocument data { get; set; } }
BsonDocument天然支持任意JSON结构的存储与序列化,ASP.NET Core会自动将Swagger提交的JSON解析为BsonDocument,直接写入MongoDB无兼容问题。
方法2:自定义JsonElement的Bson序列化器
若必须保留dynamic属性,可通过自定义序列化器让MongoDB支持JsonElement类型:
- 创建序列化器类:
public class JsonElementSerializer : IBsonSerializer<JsonElement> { public Type ValueType => typeof(JsonElement); public JsonElement Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { var bsonDoc = BsonDocumentSerializer.Instance.Deserialize(context, args); return JsonSerializer.Deserialize<JsonElement>(bsonDoc.ToJson()); } public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, JsonElement value) { var bsonDoc = BsonDocument.Parse(value.GetRawText()); BsonDocumentSerializer.Instance.Serialize(context, args, bsonDoc); } // 显式实现非泛型接口方法 object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) => Deserialize(context, args); void IBsonSerializer.Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) => Serialize(context, args, (JsonElement)value); }
- 在Program.cs中注册序列化器:
// 在添加MongoDB服务前注册 BsonSerializer.RegisterSerializer(new JsonElementSerializer()); builder.Services.AddSingleton<IMongoClient>(new MongoClient(builder.Configuration.GetConnectionString("MongoDB")));
方法3:配置ObjectSerializer允许JsonElement类型
通过全局配置让MongoDB的ObjectSerializer支持JsonElement,但此方法为全局修改,需注意潜在兼容性问题:
// 在Program.cs中添加 var objectSerializer = BsonSerializer.LookupSerializer<ObjectSerializer>(); objectSerializer.AllowTypes.Add(typeof(JsonElement));
内容的提问来源于stack exchange,提问作者Roque Rojo Bacete
相关产品推荐
相关产品推荐

