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

从NewtonSoft.Json迁移到System.Text.Json时JsonElement转换报错

问题根因

该类型转换错误由System.Text.Json的默认序列化行为导致:

  • 原Newtonsoft.Json中使用的JToken为引用类型,框架原生支持其作为字典值的反序列化,可直接接收字符串、数字、嵌套对象等任意JSON节点值,对null值也天然兼容。
  • 迁移后使用的JsonElement是结构体值类型,System.Text.Json内置转换器未对Nullable<JsonElement>(即JsonElement?)做适配,直接反序列化原始类型值(比如示例中的字符串Tags-value)时,无法完成到可空值类型包装的转换,直接抛出转换异常。
可行解决方案

方案1:移除外层可空声明(成本最低)

如果业务场景不需要显式区分"键不存在"和"键存在但值为null",直接将字典值类型改为非可空JsonElement即可,System.Text.Json原生支持该类型的反序列化:

public class A {
    public IDictionary<string, JsonElement>? Values { get; set; }
}

注意:JsonElement本身提供ValueKind枚举可判断值类型,不需要通过Nullable包装识别null值,判断逻辑如下:

// 判断字典中指定键对应的值是否为JSON null
bool isNull = Values["key"].ValueKind == JsonValueKind.Null;

方案2:添加自定义转换器(保留JsonElement?声明)

如果必须保留JsonElement?的类型定义,实现一个针对可空JsonElement的序列化转换器并全局注册即可:

  1. 编写转换器实现:
public class NullableJsonElementConverter : JsonConverter<JsonElement?>
{
    public override JsonElement? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return JsonElement.ParseValue(ref reader);
    }

    public override void Write(Utf8JsonWriter writer, JsonElement? value, JsonSerializerOptions options)
    {
        if (value.HasValue)
        {
            value.Value.WriteTo(writer);
            return;
        }
        writer.WriteNullValue();
    }
}
  1. 在ASP.NET Core的JSON配置中注册转换器:
// Program.cs中配置控制器/Minimal API的JSON选项
builder.Services.AddControllers()
    .AddJsonOptions(opts =>
    {
        opts.JsonSerializerOptions.Converters.Add(new NullableJsonElementConverter());
    });

额外排查点

如果调整类型后仍报绑定错误,检查请求体与模型结构是否匹配:

  • 你当前定义的模型类A仅包含Values属性,如果没有配置[JsonPropertyName]特性、全局属性名映射规则,示例中的请求体{"tags": {"Some-tag": "Tags-value"}}会尝试将tags绑定为A类的直接属性,而非Values字典内的键,会触发绑定失败。
  • 如果需要直接将请求体根对象作为字典接收,无需定义包装类A,直接将端点参数声明为IDictionary<string, JsonElement>类型即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:09:18