System.Text.Json类库进行json转化时 ValueKind:Object 问题

文章目录

  • 写在前面
  • 问题描述
  • 解决办法
  • 扩展 Datetime类型转换源码
  • 完整的配置

写在前面

以下方法中的所有转换器都属于刚刚能解决我的问题状态,实际使用过程中应该编写更加严谨的逻辑。

问题描述

webapi 当使用System.Text.Json类库进行json转化时,如果没有明确类型的基础类型,则会出现转换值为ValueKind:Object {xxxxx}等问题。

解决办法

通过自定义转换器实现

代码如下:

public class ObjectJsonConverter : JsonConverter<Object>
{public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options){if (reader.TokenType == JsonTokenType.String){if (DateTime.TryParse(reader.GetString(), out DateTime dateTime))return dateTime;return reader.GetString();}else if (reader.TokenType == JsonTokenType.Number){if (reader.TryGetInt32(out int intNum))return intNum;else if (reader.TryGetDouble(out double doubleNum))return doubleNum;elsereturn reader.GetDecimal();}return reader.GetDecimal();}public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options){ Type objType = value.GetType();if (value == null)writer.WriteNullValue();if (objType == typeof(string) || objType == typeof(DateTime) || objType == typeof(Guid))writer.WriteStringValue(value.ToString());else if (objType == typeof(int))writer.WriteNumberValue((int)value);else if (objType == typeof(double))writer.WriteNumberValue((double)value);else if (objType == typeof(decimal))writer.WriteNumberValue((decimal)value);else if (objType == typeof(char))writer.WriteNumberValue((char)value);else if (objType == typeof(bool))writer.WriteBooleanValue((bool)value);elsewriter.WriteStringValue(value.ToString()); }
}

在入口程序配置

// 添加Object格式化转换器
options.JsonSerializerOptions.Converters.Add(new ObjectJsonConverter());

扩展 Datetime类型转换源码

public class DateTimeJsonConverter : JsonConverter<DateTime>
{public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options){if (reader.TokenType == JsonTokenType.String){if (DateTime.TryParse(reader.GetString(), out DateTime dateTime)){return dateTime;}}return reader.GetDateTime();}public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options){writer.WriteStringValue(value.ToString("yyyy年MM月dd日 HH时mm分ss秒"));}
}

完整的配置

// Add services to the container. 
builder.Services.AddControllers().AddJsonOptions(options =>
{// 设置编码格式options.JsonSerializerOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;// 是否格式化文本options.JsonSerializerOptions.WriteIndented = true; // 字段采用驼峰式命名options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 忽略null值options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;// 忽略只读字段options.JsonSerializerOptions.IgnoreReadOnlyProperties = true;// 允许属性值末尾存在逗号options.JsonSerializerOptions.AllowTrailingCommas = true;// 处理循环引用类型options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
//枚举类型转string配置(避免转int)options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());// 添加时间格式化转换器options.JsonSerializerOptions.Converters.Add(new DateTimeJsonConverter());// 添加Object格式化转换器options.JsonSerializerOptions.Converters.Add(new ObjectJsonConverter());});