.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
相关产品推荐
相关产品推荐

