文章目录
- 写在前面
- 问题描述
- 解决办法
- 扩展 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());});