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

如何让JsonSerializer.Deserialize<>不将对象反序列化为JsonElement类型?

如何让JsonSerializer.Deserialize<>不将对象反序列化为JsonElement类型?

这个问题我之前也碰到过,System.Text.Json在反序列化为Dictionary<string, object>时,默认会把所有未知类型的JSON值包装成JsonElement,确实挺让人头疼的。不过有几种办法可以解决这个问题:

  • 方法一:利用JsonSerializerOptions.UnknownTypeHandling属性
    这是最简便的方案,只需要配置序列化选项,让序列化器自动将JSON基本类型映射为对应的.NET原生类型:
var options = new JsonSerializerOptions
{
    UnknownTypeHandling = JsonUnknownTypeHandling.Object
};

var newData = JsonSerializer.Deserialize<Dictionary<string, object>>(json, options);

// 现在这个断言会通过,Key2的值是long类型(JSON整数默认转long)
Assert.IsType<long>(newData["Key2"]);
// Key1会是string类型
Assert.IsType<string>(newData["Key1"]);
// Key3会是DateTime类型
Assert.IsType<DateTime>(newData["Key3"]);

需要注意的是,JSON中的整数默认会被转换为long而非int,如果你的业务场景必须用int,可以参考下面的自定义转换器方案。

  • 方法二:自定义JsonConverter实现精确类型控制
    如果需要更精细的类型映射(比如把JSON整数强制转成int),可以编写自定义转换器来处理object类型的反序列化:
public class ObjectConverter : JsonConverter<object>
{
    public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return reader.TokenType switch
        {
            // 优先尝试转换为int
            JsonTokenType.Number when reader.TryGetInt32(out int intValue) => intValue,
            // 再尝试long
            JsonTokenType.Number when reader.TryGetInt64(out long longValue) => longValue,
            // 浮点型转double
            JsonTokenType.Number => reader.GetDouble(),
            // 尝试转换为DateTime
            JsonTokenType.String when reader.TryGetDateTime(out DateTime dateTimeValue) => dateTimeValue,
            // 普通字符串
            JsonTokenType.String => reader.GetString(),
            // 布尔值
            JsonTokenType.True => true,
            JsonTokenType.False => false,
            // null值
            JsonTokenType.Null => null,
            // 其他类型 fallback 到JsonElement
            _ => JsonElement.ParseValue(ref reader)
        };
    }

    public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
    {
        JsonSerializer.Serialize(writer, value, value.GetType(), options);
    }
}

使用这个转换器时,只需要把它加入序列化选项的转换器集合:

var options = new JsonSerializerOptions
{
    Converters = { new ObjectConverter() }
};

var newData = JsonSerializer.Deserialize<Dictionary<string, object>>(json, options);

// 现在Key2会是int类型,这个断言可以通过
Assert.IsType<int>(newData["Key2"]);

两种方案各有优势:方法一简单高效,适合大多数通用场景;方法二灵活性强,能满足特殊的类型转换需求,你可以根据自己的业务情况选择。

备注:内容来源于stack exchange,提问作者Eric

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:05:32