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

.NET 6无外部依赖下,如何将配置变更保存到appsettings.json?

问题描述

我有一个旧的.NET 2.0桌面应用,通过标准Settings.settings存储配置,代码如下:

[Serializable]
public class AlgebraStatsParams
{
    public List<GeneratorStats> Params { get; private set; }

    public AlgebraStatsParams()
    {
        Params = new List<GeneratorStats>();
        if (Properties.Settings.Default.AlgebraStats != null)
            foreach (string settings in Properties.Settings.Default.AlgebraStats)
            {
                GeneratorStats p = GeneratorStats.FromString(settings);
                Params.Add(p);
            }
        Params.Sort();
    }

    public void SaveToConfig()
    {
        Properties.Settings.Default.Upgrade();
        Properties.Settings.Default.AlgebraStats.Clear();
        foreach (GeneratorStats p in Params)
            Properties.Settings.Default.AlgebraStats.Add(p.ToString());
        Properties.Settings.Default.Upgrade();
        Properties.Settings.Default.Save();
    }
}

现在我正将应用移植到.NET 6.0,不依赖任何非标准包,改用appsettings.json作为配置存储,初始化代码如下:

internal static class Program
{
    public static IConfiguration Configuration;

    [STAThread]
    static void Main()
    {
        var builder = new ConfigurationBuilder()
           .AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
        Configuration = builder.Build();

        ApplicationConfiguration.Initialize();
        Application.Run(new MainForm());
    }
}

但.NET 6无法像预期那样将配置变更保存到appsettings.json,尝试的代码如下:

[Serializable]
public class AlgebraStatsParams
{
    public List<GeneratorStats> Params { get; private set; }

    public AlgebraStatsParams()
    {
        Params = Program.Configuration.GetSection("StatsSettings").Get<List<GeneratorStats>>() ?? new List<GeneratorStats>();
        Params.Sort();
    }

    public void SaveToConfig()
    {
        // 我希望设置并保存appsettings
        Program.Configuration.GetSection("StatsSettings").Set(Params);
        Program.Configuration.Save();
    }
}

问题:在不依赖外部包的情况下,如何像.NET 2.0中那样简单地将配置变更保存到appsettings.json?


解决方案

.NET 6中的IConfiguration是只读设计,它仅负责加载配置数据,没有内置的保存方法。要实现修改后写入appsettings.json,需要手动使用System.Text.Json(.NET内置库)完成读写操作,具体步骤如下:

1. 先明确配置文件路径

为避免相对路径问题,在Program类中统一管理appsettings.json的完整路径:

internal static class Program
{
    public static IConfiguration Configuration;
    // 配置文件路径,默认取应用程序运行目录下的文件
    public static string AppSettingsPath = Path.Combine(AppContext.BaseDirectory, "appsettings.json");

    [STAThread]
    static void Main()
    {
        var builder = new ConfigurationBuilder()
           .AddJsonFile(AppSettingsPath, optional: true, reloadOnChange: false);
        Configuration = builder.Build();

        ApplicationConfiguration.Initialize();
        Application.Run(new MainForm());
    }
}

2. 修改保存逻辑,手动读写JSON文件

更新AlgebraStatsParams的SaveToConfig方法,实现读取、修改、回写整个JSON文件:

[Serializable]
public class AlgebraStatsParams
{
    public List<GeneratorStats> Params { get; private set; }

    public AlgebraStatsParams()
    {
        Params = Program.Configuration.GetSection("StatsSettings").Get<List<GeneratorStats>>() ?? new List<GeneratorStats>();
        Params.Sort();
    }

    public void SaveToConfig()
    {
        // 读取现有JSON内容,文件不存在则创建空对象
        string jsonContent = File.Exists(Program.AppSettingsPath) 
            ? File.ReadAllText(Program.AppSettingsPath) 
            : string.Empty;
        JsonObject jsonObj = string.IsNullOrEmpty(jsonContent)
            ? new JsonObject()
            : JsonSerializer.Deserialize<JsonObject>(jsonContent);

        // 序列化要保存的参数列表
        JsonElement statsElement = JsonSerializer.SerializeToElement(Params);

        // 更新或添加StatsSettings节点
        if (jsonObj.ContainsKey("StatsSettings"))
        {
            jsonObj["StatsSettings"] = statsElement;
        }
        else
        {
            jsonObj.Add("StatsSettings", statsElement);
        }

        // 格式化JSON并写回文件
        var serializeOptions = new JsonSerializerOptions { WriteIndented = true };
        string updatedJson = JsonSerializer.Serialize(jsonObj, serializeOptions);
        File.WriteAllText(Program.AppSettingsPath, updatedJson);

        // 可选:重新加载配置,让后续读取能获取最新值
        var configBuilder = new ConfigurationBuilder()
           .AddJsonFile(Program.AppSettingsPath, optional: true, reloadOnChange: false);
        Program.Configuration = configBuilder.Build();
    }
}

注意事项

  • 确保GeneratorStats类能被System.Text.Json正确序列化:需要有无参构造函数,或者在序列化时配置JsonSerializerOptions(比如启用IncludeFields如果类中使用字段而非属性)。
  • 权限问题:如果应用安装在Program Files等受保护目录,运行时可能没有写入权限,建议将appsettings.json放在用户目录(如Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData))下。
  • 文件不存在时,上述代码会自动创建新的appsettings.json文件。

内容的提问来源于stack exchange,提问作者amuliar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:40:19