You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 22:13:15