如何使用System.Text.Json正确序列化反序列化System.Drawing.Color
问题原因
System.Drawing.Color类型的R、G、B、A、Name等核心属性均为只读属性,System.Text.Json默认序列化规则虽然能读取这些属性值生成JSON,但反序列化时无法为只读属性赋值,最终只会生成默认的Color.Empty对象,就是你遇到的输出全0和空Color的情况。
解决方案:自定义Color类型的JsonConverter
你只需要实现针对System.Drawing.Color的自定义转换器,指定序列化和反序列化的规则即可,推荐将Color序列化为32位ARGB整数,体积小处理逻辑简单:
using System.Drawing; using System.Text.Json; using System.Text.Json.Serialization; public class ColorJsonConverter : JsonConverter<Color> { public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 读取序列化的ARGB整数值,转成Color int argb = reader.GetInt32(); return Color.FromArgb(argb); } public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) { // 把Color转成ARGB整数输出 writer.WriteNumberValue(value.ToArgb()); } }
如果你需要兼容之前已经生成的、带R/G/B/A字段的旧JSON格式,可以调整转换器逻辑:
public class ColorJsonConverter : JsonConverter<Color> { public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 兼容旧格式:读取Color的JSON对象字段 using JsonDocument doc = JsonDocument.ParseValue(ref reader); JsonElement root = doc.RootElement; byte r = root.GetProperty("R").GetByte(); byte g = root.GetProperty("G").GetByte(); byte b = root.GetProperty("B").GetByte(); byte a = root.GetProperty("A").GetByte(); return Color.FromArgb(a, r, g, b); } public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) { // 继续输出对象格式兼容旧逻辑 writer.WriteStartObject(); writer.WriteNumber("R", value.R); writer.WriteNumber("G", value.G); writer.WriteNumber("B", value.B); writer.WriteNumber("A", value.A); writer.WriteString("Name", value.Name); writer.WriteEndObject(); } }
使用方法
方法1:全局注册转换器(所有Color类型都生效)
序列化和反序列化时传入配置了转换器的JsonSerializerOptions即可:
// 配置序列化选项 var options = new JsonSerializerOptions { Converters = { new ColorJsonConverter() } }; // 序列化 File.WriteAllText("data.json", JsonSerializer.Serialize(test, options)); // 反序列化 Test test2 = JsonSerializer.Deserialize<Test>(File.ReadAllText("data.json"), options);
方法2:单独给属性加特性(只对指定属性生效)
如果不想全局生效,可以直接在Test类的Color属性上加JsonConverter特性,集合属性无需单独配置,元素类型为Color会自动匹配转换器:
public class Test { [JsonConverter(typeof(ColorJsonConverter))] public Color Farbe { get; set; } public IEnumerable<Color> Farben { get; set; } }
内容的提问来源于stack exchange,提问作者sunriax
相关产品推荐
相关产品推荐

