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

Asp.net Core接收DTO动态JSON属性存入MongoDb出现JsonValueKind异常

问题原因

ASP.NET Core 默认使用 System.Text.Json 作为请求体的序列化/反序列化组件,当你将 DTO 中的 Content 字段声明为 dynamic 或无类型的 object 时,System.Text.Json 不会将其反序列化为匹配JSON结构的动态对象,而是会解析为 System.Text.Json.JsonElement 类型的实例。
你直接将 JsonElement 实例赋值给 object 类型变量后,MongoDB C# 驱动无法识别该类型,序列化时错误提取了 JsonElement 下的 ValueKind 枚举属性作为整个对象存入数据库,你看到的存储结果中的_v:1 就是JsonValueKind.Object对应的枚举值。

解决方案

方案1:替换默认序列化器为Newtonsoft.Json(最省心)

Newtonsoft.Json对dynamic类型的反序列化逻辑和MongoDB驱动的兼容性更好,操作步骤:

  1. 安装对应版本的NuGet包:
    Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. 在服务注册逻辑中启用Newtonsoft.Json作为控制器的序列化器:
    .NET 6+ 版本在Program.cs中修改:
builder.Services.AddControllers().AddNewtonsoftJson();

.NET 5及更早版本在Startup.cs的ConfigureServices方法中修改:

services.AddControllers().AddNewtonsoftJson();

配置完成后,dynamic? Content会被反序列化为Newtonsoft.Json.Linq.JObject实例,直接赋值给object存入MongoDB即可得到正确的结构。

方案2:保留System.Text.Json,手动转换类型

如果不想更换默认序列化器,可以做如下调整:

  1. 将DTO中的Content类型显式声明为JsonElement?:
public class DocumentPostDTO
{
    public string Path { get; set; }
    public JsonElement? Content { get; set; }
}
  1. 存入MongoDB前手动转换为可识别的类型:
  • 方式A:直接转为Bson结构存入
using MongoDB.Bson;
// 直接读取JsonElement的原始JSON文本,转为BsonDocument
BsonDocument content = BsonDocument.Parse(documentDto.Content.GetRawText());
  • 方式B:转为标准动态对象
using System.Text.Json;
// 反序列化为ExpandoObject动态对象
object _content = JsonSerializer.Deserialize<ExpandoObject>(documentDto.Content.GetRawText());

转换后再存入MongoDB即可得到正确的结构。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 14:45:05