商城首页欢迎来到中国正版软件门户

您的位置:首页 >C#怎么实现配置文件读写_C#如何读取App.config和appsettings.json【教程】

C#怎么实现配置文件读写_C#如何读取App.config和appsettings.json【教程】

  发布于2026-04-28 阅读(0)

扫一扫,手机访问

C#怎么实现配置文件读写_C#如何读取App.config和appsettings.json【教程】

C#怎么实现配置文件读写_C#如何读取App.config和appsettings.json【教程】

开门见山,先说一个核心结论:App.config 在现代 .NET 开发中已经出局,而 appsettings.json 虽然是标准,但它的设计初衷是“只读”的。 这意味着,如果你想让应用在运行时动态修改配置并持久化保存,指望框架自动帮你双向同步,那可就找错方向了。真正的解决方案,是手动构建配置对象并直接操作 JSON 文件本身。

App.config 在现代 C# 项目里根本不能“写”

首先得明确,App.config 是 .NET Framework 时代的产物。那时候,大家习惯用 ConfigurationManager.AppSettings[“key”] 来读取配置,感觉挺方便。但问题在于,这个机制从设计上就是只读的。你或许尝试过修改值然后调用 Sa ve(),结果发现要么不生效,要么只在当前进程内存里变了一下,应用一重启,改动就全丢了。

到了 .NET Core / .NET 5+ 的时代,情况就更彻底了:

  • 新建的 .NET 6/7/8 项目,默认根本不会包含 App.config 文件。
  • 即便你手动添加一个,运行时也不会自动加载它。
  • 更关键的是,即便你强行想用旧方法,比如调用 ConfigurationManager.OpenExeConfiguration,在 .NET Core+ 平台上,等待你的很可能是一个 PlatformNotSupportedException 异常。Visual Studio 编译时确实会把 App.config 复制为 MyApp.exe.config,但运行时根本不会监听这个文件的任何变更。

所以,结论很清晰:对于新项目,App.config 这条路可以直接放弃了。

appsettings.json 只能读,不能直接写

既然 App.config 不行,那转向标准的 appsettings.json 总可以了吧?很遗憾,这里也有一个常见的误解。我们通过依赖注入拿到的 IConfiguration 接口,它提供的是 GetSection()GetValue() 等一系列读取方法,但翻遍文档,你也找不到一个官方的 Set()Sa ve() 方法。

这是为什么呢?因为 IConfiguration 本质上是一个配置源的只读快照。它的背后可能串联着 JSON 文件、环境变量、命令行参数、内存字典等多个来源。这种设计是为了灵活性和优先级合并,但也意味着它没有“写回”某个特定源(比如 JSON 文件)的职责。

  • 如果你试图通过一些“黑魔法”(比如强制转换类型)去修改 IConfiguration 实例内部的状态,这属于未公开的行为,不同版本的 .NET SDK 可能导致不可预知的后果,甚至程序崩溃。
  • 当然,你可以手动用 JsonSerializer.Serialize() 把配置写回 JSON 文件,但这意味着你必须自己处理一堆麻烦事:并发写入冲突、保持 JSON 的格式缩进、处理注释丢失等等。
  • 还有一个棘手的问题:如果你的配置项混合了多个来源(比如数据库连接字符串来自 appsettings.json,而日志级别来自环境变量),那么“写回文件”这个操作本身就无法还原这种复杂的来源逻辑。

所以,appsettings.json 本身不是用来“写”的,IConfiguration 也不是那个负责持久化的对象。

真要实现“可写配置”,得绕过 IConfiguration 直接操作 JSON 文件

那么,正确的姿势到底是什么?答案是:绕过 IConfiguration 的只读抽象层,直接对 appsettings.json 这个物理文件进行读写操作。 这是最可控、最可预测的方法。

具体步骤可以分解如下:

  • 读取与解析:首先,使用 File.ReadAllText(“appsettings.json”) 将文件内容完整读入,然后通过 System.Text.JsonNewtonsoft.Json 将其反序列化。你可以反序列化为灵活的 JsonDocument,或者更常见的,映射到一个预先定义好的 POCO(普通C#类)模型上。
  • 修改配置:在内存中修改这个模型对象的属性值,比如 settings.Logging.LogLevel.Default = “Debug”;
  • 写回与重载:使用 JSON 序列化器将修改后的对象重新序列化为字符串,并用 File.WriteAllText 写回原文件。这里有个关键点:为了保持文件可读性,建议在序列化时设置 WriteIndented = true。写入完成后,调用之前保存的 IConfigurationRoot.Reload() 方法,触发配置系统重新加载文件,使改动立即生效。
// 构建配置时,确保获取到 IConfigurationRoot 的引用
var config = new ConfigurationBuilder()
    .AddJsonFile(“appsettings.json”, optional: false, reloadOnChange: true)
    .Build();
var root = (IConfigurationRoot)config;

// 直接读写 JSON 文件
var settings = JsonSerializer.Deserialize(File.ReadAllText(“appsettings.json”));
settings.Logging.LogLevel.Default = “Debug”;
File.WriteAllText(“appsettings.json”, JsonSerializer.Serialize(settings, new JsonSerializerOptions { WriteIndented = true }));

// 触发配置重载
root.Reload();

需要提醒的是,在写回文件前,强烈建议对原文件进行备份。这样可以防止万一序列化过程出错导致 JSON 格式损坏,从而避免应用下次启动时直接失败。

别忽略 reloadOnChange 和文件权限这两个硬限制

即使你按照上面的流程操作,还有两个底层限制必须心里有数,它们常常在部署后成为“幽灵问题”。

第一个是关于 reloadOnChange: true。这个选项依赖于 FileSystemWatcher 来监听文件变化,但它并非百分百可靠:

  • 在 Docker 容器环境中,尤其是 Windows 主机搭配 Linux 容器时,挂载卷(Volume)的文件变更事件经常无法正确触发。
  • 如果 appsettings.json 文件被其他进程(如 Visual Studio 正在编辑,或者记事本没有关闭)以独占方式打开,重载可能会静默失败。

第二个,也是更实际的限制,是文件系统权限

  • 在 Linux 系统上部署时,如果运行应用的用户(比如 www-data)没有对 appsettings.json 文件的读取权限,应用在启动阶段就会抛出 UnauthorizedAccessException,根本到不了运行时。
  • 而“写”配置时,问题更突出:appsettings.json 通常位于应用程序集相同的目录。在生产环境中,无论是 Linux 的 systemd 服务还是 Windows 服务,其运行账户默认往往没有对该目录的写入权限。如果你没提前配置好权限,写文件时会直接抛出异常。

所以,在实现可写配置功能的同时,务必把权限检查和异常处理纳入考量范围,这才是真正稳健的做法。

本文转载于:https://www.php.cn/faq/2382738.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注