使用System.Text.Json反序列化含Font属性类时遇无参构造函数错误
解决System.Text.Json反序列化Font类型的无参构造函数错误
问题根源在于System.Drawing.Font没有公共无参构造函数,而System.Text.Json默认依赖无参构造函数实例化对象,因此反序列化时触发报错。要解决这个问题,需要自定义JsonConverter<Font>,手动处理Font的序列化与反序列化逻辑。
步骤1:实现Font的JSON转换器
创建继承自JsonConverter<Font>的类,序列化时提取Font的关键属性,反序列化时用这些属性重建Font对象:
using System.Drawing; using System.Text.Json; using System.Text.Json.Serialization; public class FontConverter : JsonConverter<Font> { public override Font Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var fontProps = JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options); // 提取Font核心属性,可根据需求补充更多属性(如GdiCharSet等) var fontFamily = (string)fontProps["Name"]; var emSize = Convert.ToSingle(fontProps["Size"]); var style = (FontStyle)Enum.Parse(typeof(FontStyle), fontProps["Style"].ToString()); var unit = (GraphicsUnit)Enum.Parse(typeof(GraphicsUnit), fontProps["Unit"].ToString()); return new Font(fontFamily, emSize, style, unit); } public override void Write(Utf8JsonWriter writer, Font value, JsonSerializerOptions options) { // 序列化时输出Font关键属性 writer.WriteStartObject(); writer.WriteString("Name", value.Name); writer.WriteNumber("Size", value.Size); writer.WriteString("Style", value.Style.ToString()); writer.WriteString("Unit", value.Unit.ToString()); writer.WriteEndObject(); } }
步骤2:注册转换器并修改序列化逻辑
在WinForms代码中创建JsonSerializerOptions并注册自定义转换器,替换原有序列化/反序列化逻辑:
using System.Text.Json; namespace WinFormsApp1; public partial class Form1 : Form { private CasaSettings _casaSettings; private string _stringJson; // 全局序列化选项,注册Font转换器 private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { Converters = { new FontConverter() }, WriteIndented = true // 可选,格式化JSON便于查看 }; public Form1() { InitializeComponent(); _casaSettings = new CasaSettings(); } private void button1_Click(object sender, EventArgs e) { _casaSettings.DefaultFont = textBox1.Font; _stringJson = JsonSerializer.Serialize(_casaSettings, _jsonOptions); } private void button2_Click(object sender, EventArgs e) { CasaSettings convertedSetting = JsonSerializer.Deserialize<CasaSettings>(_stringJson, _jsonOptions); // 可验证结果:textBox2.Font = convertedSetting.DefaultFont; } } public class CasaSettings { public CasaSettings() { } public int AlertIntervalRefresh { get; set; } = 60000; public Font DefaultFont { get; set; } = new Font("Tahoma", (float)8.25, GraphicsUnit.Point); }
补充说明
如果需要保留Font的更多细节(如GDI垂直字体、字符集等),可在转换器的Write方法中添加对应属性,在Read方法中提取后传入Font的重载构造函数即可。
内容的提问来源于stack exchange,提问作者RPAlbert
相关产品推荐
相关产品推荐

