c# System.Text.Json 反序列化Dictionary<string,object>时未转换基础类型的处理方法

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 以及解决方案

posted @ 2026-04-07 14:15  Hey,Coder!  阅读(12)  评论(0)    收藏  举报