在 System.Text.Json 内置的转换器集合中,涵盖了所有的基础数据类型,这些转换器的设计非常精妙,他们通过注册一系列的类型映射,在通过 Utf8JsonWriter/Utf8JsonReader 的内置方法 GetTypeValue/TryGetTypeValue 方法得到值,代码非常精练,复用性非常高,下面是内置类型转换器。
private static IEnumerable<JsonConverter> DefaultSimpleConverters { get { // When adding to this, update NumberOfSimpleConverters above. yield return new JsonConverterBoolean(); yield return new JsonConverterByte(); yield return new JsonConverterByteArray(); yield return new JsonConverterChar(); yield return new JsonConverterDateTime(); yield return new JsonConverterDateTimeOffset(); yield return new JsonConverterDouble(); yield return new JsonConverterDecimal(); yield return new JsonConverterGuid(); yield return new JsonConverterInt16(); yield return new JsonConverterInt32(); yield return new JsonConverterInt64(); yield return new JsonConverterJsonElement(); yield return new JsonConverterObject(); yield return new JsonConverterSByte(); yield return new JsonConverterSingle(); yield return new JsonConverterString(); yield return new JsonConverterUInt16(); yield return new JsonConverterUInt32(); yield return new JsonConverterUInt64(); yield return new JsonConverterUri(); } } 自定义类型转换器虽然 System.Text.Json 内置了各种各样丰富的类型转换器,但是在各种业务开发的过程中,总会根据业务需求来决定一些特殊的数据类型的数据,下面,我们就以经典的日期/时间转换作为演示场景。
我们需要将日期类型输出为 Unix 时间戳而不是格式化的日期内容,为此,我们将实现一个自定义的时间格式转换器,该转换器继承自 JsonConverter。
public class JsonConverterUnixDateTime : JsonConverter<DateTime> { private static DateTime Greenwich_Mean_Time = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Local); private const int Limit = 10000; public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.Number) { var unixTime = reader.GetInt64(); var dt = new DateTime(Greenwich_Mean_Time.Ticks + unixTime * Limit); return dt; } else { return reader.GetDateTime(); } } public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { var unixTime = (value - Greenwich_Mean_Time).Ticks / Limit; writer.WriteNumberValue(unixTime); } } 应用自定义的时间转换器转换器的应用形式有两种,分别是将转换加入 JsonSerializerOptions.Converters 和给需要转换的属性添加特性标记 JsonConverter
加入Converters 方式 var options = new JsonSerializerOptions(); options.Converters.Add(new JsonConverterUnixDateTime()); var user = new UserInfo() { Age = 30, Name = "Ron", LoginTime = DateTime.Now }; var json = JsonSerializer.Serialize(user, options); var deUser = JsonSerializer.Deserialize<UserInfo>(json, options); // JSON 输出 {"Name":"Ron","Age":30,"LoginTime":1577655080422} 应用 JsonConverter 特性方式 public class UserInfo { public string Name { get; set; } public int Age { get; set; } [JsonConverter(typeof(JsonConverterUnixDateTime))] public DateTime LoginTime { get; set; } } var user = new UserInfo() { Age = 30, Name = "Ron", LoginTime = DateTime.Now }; var json = JsonSerializer.Serialize(user); var deUser = JsonSerializer.Deserialize<UserInfo>(json); // JSON 输出 {"Name":"Ron","Age":30,"LoginTime":1577655080422}注意上面的 UserInfo.LoginTime 的特性标记,当你想小范围的对某些属性单独应用转换器的时候,这种方式费用小巧而有效。
结束语本文全面的介绍了 System.Text.Json 在各种场景下的用法,并比较和 Newtonsoft.Json 使用上的不同,也通过实例演示了具体的使用方法,进一步深入讲解了 System.Text.Json 各种对象的原理,希望对大家在迁移到.NETCore-3.1 的时候有所帮助。
最后,欢迎点赞!