欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于动态修改App.Config与web.Config的使用详解

程序员文章站 2023-12-16 23:47:58
首先假设你的应用程序配置文件如下:复制代码 代码如下:

首先假设你的应用程序配置文件如下:

复制代码 代码如下:

<?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 中。

代码如下:

复制代码 代码如下:

public static void main()
{
    console.writeline(configurationmanager.appsettings["name"]);
    changeconfiguration();
    console.writeline(configurationmanager.appsettings["name"]);
    console.readline();
}

private static void changeconfiguration()
{
    //读取程序集的配置文件
    string assemblyconfigfile = assembly.getentryassembly().location;

    configuration config = configurationmanager.openexeconfiguration(assemblyconfigfile);
    //获取appsettings节点
    appsettingssection appsettings = (appsettingssection)config.getsection("appsettings");
   

    //删除name,然后添加新值
    appsettings.settings.remove("name");
    appsettings.settings.add("name", "new");

    //保存配置文件
    config.save();
}


代码很简单:首先读取配置文件,接着获取appsettings节点,然后修改,接着保存。

运行:结果如下:

基于动态修改App.Config与web.Config的使用详解

可以看到输出的值是两个old.

为什么??

查找msdn文档可以发现微软出于性能考虑,对configurationmanager采用了缓存策略,所以如果要读取新的值,应该使用configurationmanagerrefreshsection来进行刷新,

configurationmanager . refreshsection:

刷新命名节,这样在下次检索它时将从磁盘重新读取它。

于是将main方法修改为:

console.writeline(configurationmanager.appsettings["name"]);

changeconfiguration();

configurationmanager.refreshsection("appsettings");

console.writeline(configurationmanager.appsettings["name"]);

重新清理解决方案,重新运行:

基于动态修改App.Config与web.Config的使用详解

可以看到,仍然是两个old。。。

为什么??  

难道值没有修改??,我们打开应用程序的配置文件,可以通过监视assemblyconfigfile获得路径

上面是xxx\bin\debug\castudy.exe.,对应的配置文件就是castudy.exe.config

基于动态修改App.Config与web.Config的使用详解

文件的内容如下:

基于动态修改App.Config与web.Config的使用详解

 

可以发现value 值已经更改,那么为什么输出还是old,old 呢??

 

为了验证不是vs2010的问题。

首先手动将castudy.exe.config 文件中的value改为”old”,接着再次运行castudy.exe 结果如下:

基于动态修改App.Config与web.Config的使用详解 

可以看到输出时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()方法修改如下:

复制代码 代码如下:

private static void changeconfiguration()
{

    //读取程序集的配置文件
    string assemblyconfigfile = assembly.getentryassembly().location;
    string appdomainconfigfile = appdomain.currentdomain.setupinformation.configurationfile;

    configuration config = configurationmanager.openexeconfiguration(configurationuserlevel.none);
   

     //获取appsettings节点
    appsettingssection appsettings = (appsettingssection)config.getsection("appsettings");
   

    //删除name,然后添加新值
    appsettings.settings.remove("name");
    appsettings.settings.add("name", "new");

    //保存配置文件
    config.save();
}


清理,重新运行:

使用默认的不传递字符串的版本就可以打开当前配置文件了。

configuration config = configurationmanager.openexeconfiguration(configurationuserlevel.none);

如果要查看当前配置文件的完整路径可以使用appdomain.currentdomain.setupinformation.configurationfile;

重新运行,结果如下:

基于动态修改App.Config与web.Config的使用详解 

另外值得一提的是: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");

上一篇:

下一篇: