App.config是.NET应用程序中非常基础但又极其重要的一个文件,它承载着数据库连接字符串、自定义参数、运行时行为等各种配置信息。很多刚接触.NET开发的朋友对这个文件的理解停留在“往里面写点键值对”的层面,遇到配置不生效、发布后被覆盖、敏感信息明文存储等问题时往往束手无策。本文将从文件结构、读写方式、加密保护以及常见问题排查几个角度,把App.config的使用要点系统地梳理一遍。

一、App.config的基本结构与常用节点
App.config本质上是一个XML文件,位于项目根目录下。编译输出时,它会被自动重命名为“程序集名.exe.config”,例如你的程序叫MyApp.exe,那么输出目录里就会生成MyApp.exe.config,运行时读取的正是这个文件而不是源码目录里的App.config。理解这一点非常关键,很多“改了配置没生效”的问题都源于改错了文件。
文件内部由多个配置节组成,其中最常用的是appSettings和connectionStrings。appSettings以键值对形式存放自定义配置,适合放一些开关、路径、超时时间等轻量参数;connectionStrings专门用来管理数据库连接字符串,它提供了name、connectionString和providerName三个属性,方便集中管理多个数据源。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LogLevel" value="Info"/>
<add key="MaxRetryCount" value="3"/>
</appSettings>
<connectionStrings>
<add name="DefaultDb"
connectionString="Data Source=192.168.0.1;Initial Catalog=OrderDb;User ID=sa;Password=******"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>需要注意的是,如果同一个key出现两次,程序启动时会直接抛出配置重复的异常。此外,自定义配置节还可以通过configSections来声明,进而实现结构更复杂的配置模型,比如嵌套的集合、枚举类型等,这在大型项目中能让配置语义更清晰。
二、在代码中读取与修改配置项
读取配置最常用的方式是ConfigurationManager类,它位于System.Configuration命名空间下,使用前需确认项目已引用对应的程序集。读取appSettings用AppSettings属性,读取连接字符串用ConnectionStrings属性,两者都支持按键名索引访问,取不到时返回null而非抛异常,所以要做好空值判断。
using System;
using System.Configuration;
class Program
{
static void Main()
{
// 读取appSettings中的值
string logLevel = ConfigurationManager.AppSettings["LogLevel"];
int retryCount = int.Parse(ConfigurationManager.AppSettings["MaxRetryCount"] ?? "0");
// 读取连接字符串
var connStr = ConfigurationManager.ConnectionStrings["DefaultDb"]?.ConnectionString;
Console.WriteLine($"日志级别:{logLevel},重试次数:{retryCount}");
// 动态写入配置(修改的是输出目录中的.config文件)
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["LogLevel"].Value = "Debug";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
}这里有一个容易踩的坑:ConfigurationManager.AppSettings读取的值会被缓存,程序不重启的话,直接用文本编辑器改配置文件后再读取,拿到的仍是旧值。解决办法是调用RefreshSection方法刷新对应节点,或者干脆在需要时重新打开配置。另外,config.Save()要求对输出目录有写权限,如果程序安装在C:\Program Files下,普通用户身份运行时写入会失败,可以考虑把可变配置放到用户级配置文件中。
在ASP.NET网站项目中,对应的文件是Web.config而不是App.config,读取API基本一致,但Web.config在网站运行中修改会触发应用域重启,这一点在做在线更新配置功能时必须考虑,否则会导致用户会话丢失。
三、敏感配置的加密保护
连接字符串里往往包含数据库账号密码,明文放在配置文件中存在泄露风险,尤其当代码库被提交到版本控制系统时,问题更加严重。.NET内置的RSAProtectedConfigurationProvider和DPAPIProtectedConfigurationProvider可以对配置节进行加密,加密后的文件在机器上呈现为一段密文,但程序代码读取时完全不用做任何修改,框架会自动解密。
使用aspnet_regiis工具加密Web.config的命令如下,App.config也可以借助该工具配合参数处理:
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319 aspnet_regiis -pe "connectionStrings" -app "/MyWebSite" -prov "RsaProtectedConfigurationProvider"
DPAPI方式加密绑定在具体机器上,适合单服务器部署;RSA方式可以导出密钥容器,方便在负载均衡的多台机器间共享解密能力。除了内置方案,实践中也常用“配置中心+环境变量”的思路:把敏感信息从文件中移出去,通过CI/CD流水线在部署时注入,代码里只用ConfigurationBuilder按优先级读取环境变量和文件配置。这种做法在容器化部署场景下已经是主流。
四、常见问题排查思路
第一个高频问题是“改了App.config不生效”。排查顺序建议是:先确认改的是输出目录下的.exe.config文件还是源码文件;再检查项目是否设置了“较新则复制”;最后看是否有配置缓存未刷新。如果是单元测试项目,测试运行时读取的又是测试程序集对应的配置文件,很多人在类库项目里写配置却发现测试读不到,原因就在这里——配置应该写在最终可执行项目的App.config中。
第二个问题是“发布后配置被覆盖”。使用VS发布功能时,如果用了默认的发布配置,线上已有的自定义配置可能被开发环境的版本覆盖。解决办法是在发布配置文件中勾选“发布期间删除目标位置的其他文件”之外的选项组合,或者干脆把环境差异配置放到独立的environment.config中,再用configSource属性引用拆分:
<connectionStrings configSource="connectionStrings.config"/>
这样主配置文件保持稳定,各环境的差异内容各自维护,发布时只需要保留对应的子配置文件即可。整体来说,配置管理虽然琐碎,但只要理清文件加载机制、读写时机和加密手段这几层关系,App.config就能成为项目中可靠而灵活的配置载体。
App.config配置文件ASP.NET修改时间:2026-09-15 19:50:35