基于动态修改App.Config与web.Config的使用详解
首先假设你的应用程序配置文件如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appsettings>
<add key="name" value="old"/>
</appsettings>
</configuration>
ok,那么如何在运行时去修改name的值呢??
有很多童鞋会说可以使用xml读取配置文件,然后xxx。。。。
当然这种方法肯定可以解决问题,有没有其他方法呢??
在这里我要介绍一种比较简单的方法,可能已经有人知道了,那就是使用configurationmanager类
configurationmanager 存在system.configuration.dll 中。
代码如下:
private static void changeconfiguration() configuration config = configurationmanager.openexeconfiguration(assemblyconfigfile); //删除name,然后添加新值 //保存配置文件
运行:结果如下: 可以看到输出的值是两个old. 为什么??
查找msdn文档可以发现微软出于性能考虑,对configurationmanager采用了缓存策略,所以如果要读取新的值,应该使用configurationmanager的refreshsection来进行刷新, configurationmanager . refreshsection:
刷新命名节,这样在下次检索它时将从磁盘重新读取它。 于是将main方法修改为:
console.writeline(configurationmanager.appsettings["name"]); changeconfiguration(); configurationmanager.refreshsection("appsettings");
console.writeline(configurationmanager.appsettings["name"]);
重新清理解决方案,重新运行: 可以看到,仍然是两个old。。。 为什么?? 难道值没有修改??,我们打开应用程序的配置文件,可以通过监视assemblyconfigfile获得路径 上面是xxx\bin\debug\castudy.exe.,对应的配置文件就是castudy.exe.config 文件的内容如下:
可以发现value 值已经更改,那么为什么输出还是old,old 呢??
为了验证不是vs2010的问题。 首先手动将castudy.exe.config 文件中的value改为”old”,接着再次运行castudy.exe 结果如下: 可以看到输出时old,和new。为什么会这样???
难道调试时读取的不是修改的配置文件,或者修改的配置文件并不是调试的应用程序读取的文件?? 在assemblyconfigfile 中设置断点,可以发现assemblyconfigfile 读取的是castudy.exe.config。但是vs调试的时候运行的是castudy.vshost.exe。也就是说我们使用configurationmanager.openexeconfiguration 打开的是castudy.exe.config文件,但是我们调试的应用程序castudy.vshost.exe使用的是castudy.vshost.exe.config文件。 那么还有其他的方式可以准确的获取应用程序配置文件吗?? 有的,使用appdomain.currentdomain.setupinformation.configurationfile; 将changeconfiguration()方法修改如下:
//读取程序集的配置文件 configuration config = configurationmanager.openexeconfiguration(configurationuserlevel.none); //获取appsettings节点 //删除name,然后添加新值 //保存配置文件
使用默认的不传递字符串的版本就可以打开当前配置文件了。 configuration config = configurationmanager.openexeconfiguration(configurationuserlevel.none); 如果要查看当前配置文件的完整路径可以使用appdomain.currentdomain.setupinformation.configurationfile; 重新运行,结果如下: 另外值得一提的是:configurationmanager.refreshsection 不支持section group.所以对于wcf的服务,你必须一个一个的refreshsection: configurationmanager.refreshsection("system.servicemodel/behaviors"); configurationmanager.refreshsection("system.servicemodel/bindings"); configurationmanager.refreshsection("system.servicemodel/client"); configurationmanager.refreshsection("system.servicemodel/services");
public static void main()
{
console.writeline(configurationmanager.appsettings["name"]);
changeconfiguration();
console.writeline(configurationmanager.appsettings["name"]);
console.readline();
}
{
//读取程序集的配置文件
string assemblyconfigfile = assembly.getentryassembly().location;
//获取appsettings节点
appsettingssection appsettings = (appsettingssection)config.getsection("appsettings");
appsettings.settings.remove("name");
appsettings.settings.add("name", "new");
config.save();
}
代码很简单:首先读取配置文件,接着获取appsettings节点,然后修改,接着保存。
private static void changeconfiguration()
{
string assemblyconfigfile = assembly.getentryassembly().location;
string appdomainconfigfile = appdomain.currentdomain.setupinformation.configurationfile;
appsettingssection appsettings = (appsettingssection)config.getsection("appsettings");
appsettings.settings.remove("name");
appsettings.settings.add("name", "new");
config.save();
}
清理,重新运行: