惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
H
Help Net Security
GbyAI
GbyAI
博客园_首页
G
Google Developers Blog
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
月光博客
月光博客
美团技术团队
B
Blog RSS Feed
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
博客园 - 叶小钗
有赞技术团队
有赞技术团队
T
The Blog of Author Tim Ferriss
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Proofpoint News Feed

博客园 - Hey,Coder!

微信小程序 web方案实现调音器功能 systemctl slice配置docker最大占用cpu 内存 pipenv环境变量配置 .net8验证码 数据库差异对比工具 docker部署prometheus grafana pgexporter Alertmanager ubuntu24 换源 ssh配置 ubuntu24 Harbor部署 ubuntu24 kvm部署 cockpit web管理界面 .net api代理 Ubuntu 24.04 DMAR IOMMU 报错修复 uniapp iOS App 上架 vs文件软链接 Docker 网络别名 .net8通用中间件处理公共返回值结构 .net环境下OpenTelemetry Body 读取注意事项 jaeger界面显示异常 .net opentelemetry collector jaeger c# opentelemetry 自定义export c# opentelemetry 自定义export c# 生成对象的初始化代码 Elasticsearch ILM 与 Data Stream 概念及实例说明文档 portainer httphelper封装 Ocelot + Consul + SignalR 粘性会话 正交软件架构 docker postgresql17 主从复制 rabbitmq总结与c#示例 docker rabbitmq quartz dashboard
c# System.Text.Json 反序列化Dictionary<string,object&g...
Hey,Coder! · 2026-04-07 · via 博客园 - Hey,Coder!
public class ObjectToInferredTypesConverter
       : JsonConverter<object>
        {
            public override object Read(
                ref Utf8JsonReader reader,
                Type typeToConvert,
                JsonSerializerOptions options)
            {
                if (reader.TokenType == JsonTokenType.True)
                {
                    return true;
                }

                if (reader.TokenType == JsonTokenType.False)
                {
                    return false;
                }

                if (reader.TokenType == JsonTokenType.Number)
                {
                    if (reader.TryGetInt64(out long l))
                    {
                        return l;
                    }

                    return reader.GetDouble();
                }

                if (reader.TokenType == JsonTokenType.String)
                {
                    if (reader.TryGetDateTime(out DateTime datetime))
                    {
                        return datetime;
                    }

                    return reader.GetString();
                }

                // Use JsonElement as fallback.
                // Newtonsoft uses JArray or JObject.
                using JsonDocument document = JsonDocument.ParseValue(ref reader);
                return document.RootElement.Clone();
            }

                public override void Write(
Utf8JsonWriter writer,
object objectToWrite,
JsonSerializerOptions options)
    {
        if (objectToWrite == null)
        {
            writer.WriteNullValue();
            return;
        }

        var type = objectToWrite.GetType();

        // 处理基本类型
        switch (Type.GetTypeCode(type))
        {
            case TypeCode.Boolean:
                writer.WriteBooleanValue((bool)objectToWrite);
                return;
            case TypeCode.Byte:
                writer.WriteNumberValue((byte)objectToWrite);
                return;
            case TypeCode.SByte:
                writer.WriteNumberValue((sbyte)objectToWrite);
                return;
            case TypeCode.Int16:
                writer.WriteNumberValue((short)objectToWrite);
                return;
            case TypeCode.UInt16:
                writer.WriteNumberValue((ushort)objectToWrite);
                return;
            case TypeCode.Int32:
                writer.WriteNumberValue((int)objectToWrite);
                return;
            case TypeCode.UInt32:
                writer.WriteNumberValue((uint)objectToWrite);
                return;
            case TypeCode.Int64:
                writer.WriteNumberValue((long)objectToWrite);
                return;
            case TypeCode.UInt64:
                writer.WriteNumberValue((ulong)objectToWrite);
                return;
            case TypeCode.Single:
                writer.WriteNumberValue((float)objectToWrite);
                return;
            case TypeCode.Double:
                writer.WriteNumberValue((double)objectToWrite);
                return;
            case TypeCode.Decimal:
                writer.WriteNumberValue((decimal)objectToWrite);
                return;
            case TypeCode.String:
                writer.WriteStringValue((string)objectToWrite);
                return;
            case TypeCode.Char:
                writer.WriteStringValue(objectToWrite.ToString());
                return;
            case TypeCode.DateTime:
                writer.WriteStringValue((DateTime)objectToWrite);
                return;
        }

        // 处理 JsonElement(这是 Read 方法中可能返回的类型)
        if (objectToWrite is JsonElement jsonElement)
        {
            jsonElement.WriteTo(writer);
            return;
        }

        // 处理其他类型
        if (type == typeof(Guid) || type == typeof(Guid?))
        {
            writer.WriteStringValue(objectToWrite.ToString());
            return;
        }

        if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
        {
            writer.WriteStringValue((DateTimeOffset)objectToWrite);
            return;
        }

        if (type == typeof(TimeSpan) || type == typeof(TimeSpan?))
        {
            writer.WriteStringValue(objectToWrite.ToString());
            return;
        }

        // 处理数组
        if (type.IsArray)
        {
            writer.WriteStartArray();
            var array = (Array)objectToWrite;
            foreach (var item in array)
            {
                Write(writer, item, options);
            }
            writer.WriteEndArray();
            return;
        }

        // 处理 IEnumerable 类型
        if (objectToWrite is System.Collections.IEnumerable enumerable)
        {
            writer.WriteStartArray();
            foreach (var item in enumerable)
            {
                Write(writer, item, options);
            }
            writer.WriteEndArray();
            return;
        }

        // 对于复杂对象,使用默认的序列化方式
        // 注意:为了避免递归调用当前转换器,我们需要创建一个新的选项
        var newOptions = new JsonSerializerOptions(options);
        newOptions.Converters.Remove(this);

        JsonSerializer.Serialize(writer, objectToWrite, newOptions);
    }
        }



//注入配置、或在反序列化时指定转换器
//1. 全局配置
 builder.AddJsonOptions(options =>
 {
     options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter());

 });

//2. 反序列化时指定转换器
  var options = new JsonSerializerOptions
  {
      Converters = { new ObjectToInferredTypesConverter() }
  };
  var parseData = JsonSerializer.Deserialize<Dictionary<string, object>(jsonString, options);

公共方法封装

public static class JsonUtil
{
    public static T GetJsonObj<T>(object obj)
    {
        var jsonString = System.Text.Json.JsonSerializer.Serialize(obj);

        // 解析所有的字段
        var options = new JsonSerializerOptions
        {
            Converters = { new ObjectToInferredTypesConverter() }
        };
        var parseData = JsonSerializer.Deserialize<T>(jsonString, options);

        return parseData;
    }
}

[参考]
netcore 底层序列化Dictionary<string,object> 对象的一个Bug 以及解决方案