net9.0 中System.Text.Json 测试惊喜的发现当前版本循环引用序列化未报错,并且能正常序列化成功,故做此记录。测试结果仅做参考!!!
配置选项
# 配置说明
JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true, // 属性名称大小写不敏感
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 属性名称使用驼峰命名规则
WriteIndented = true, // 设置格式化输出
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // 允许特殊字符
ReadCommentHandling = JsonCommentHandling.Skip, // 忽略注释
AllowTrailingCommas = true, // 忽略尾随逗号
NumberHandling = JsonNumberHandling.AllowReadingFromString, // 允许数字字符串
Converters = { new DatetimeJsonConverter() } // 注册你的自定义转换器,
};
DatetimeJsonConverter 自定义解析
/// <summary>
/// 时间字符串格式化
/// </summary>
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 date))
return date;
}
return reader.GetDateTime();
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss"));
}
}
/// <summary>
/// Unix格式时间格式化
/// </summary>
public class UnixTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
if (long.TryParse(reader.GetString(), out long timestamp))
return DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;
}
if (reader.TokenType == JsonTokenType.Number)
{
long timestamp = reader.GetInt64();
return DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;
}
return reader.GetDateTime();
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
long timestamp = new DateTimeOffset(value).ToUnixTimeSeconds();
writer.WriteStringValue(timestamp.ToString());
}
}
测试
public class TestJson
{
/// <summary>
/// 名称
/// </summary>
public string? Name { get; set; }
public TestBaseJson TestBaseJson { get; set;}
}
//[JsonPolymorphic(TypeDiscriminatorPropertyName = "TestBaseJson")]
//[JsonDerivedType(typeof(TestBaseJson))]
public class TestBaseJson
{
public string? Name { get; set; }
public int Id { get; set; }
public TestBaseJson TestBase { get; set; }
}
TestJson testJson =new() {
Name = "ces",
Date=DateTime.Now,
TestBaseJson = new TestBaseJson() {
Id = 123, Name = "测试",
TestBase = new TestBaseJson() {
Id = 123, Name = "2222"
} }
};
JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true, // 属性名称大小写不敏感
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, // 属性名称使用驼峰命名规则
WriteIndented = true, // 设置格式化输出
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // 允许特殊字符
ReadCommentHandling = JsonCommentHandling.Skip, // 忽略注释
AllowTrailingCommas = true, // 忽略尾随逗号
NumberHandling = JsonNumberHandling.AllowReadingFromString, // 允许数字字符串
Converters = { new DatetimeJsonConverter() } // 注册你的自定义转换器,
};
// 序列化
Console.WriteLine(JsonSerializer.Serialize(testJson, jsonSerializerOptions));
// 反序列化
//string jsonStr = "{\r\n \"name\": \"ces\",\r\n \"testBaseJson\": {\r\n \"name\": \"测试\",\r\n \"id\": 123,\r\n \"testBase\": {\r\n \"name\": \"2222\",\r\n \"id\": 123,\r\n \"testBase\": null\r\n }\r\n },\r\n \"date\": \"2025-04-08 10:19:43\"\r\n}";
// 或者
string jsonStr = "{\"name\":\"ces\",\"testBaseJson\":{\"Name\":\"测试\",\"id\":\"123\",\"testBase\":{\"name\":\"2222\",\"id\":123,\"testBase\":null,}},\"date\":\"2025-04-08 10:19:43\"}";
// 这里加了多余逗号,数字字符串,大小写等,进行反序列化
TestJson testJson2 = JsonSerializer.Deserialize<TestJson>(jsonStr, jsonSerializerOptions);

