C# 如何在运行时更新(添加/修改/删除)web.config的AppSettings部分中的键

C# 如何在运行时更新(添加/修改/删除)web.config的AppSettings部分中的键,c#,web-config,asp.net-4.0,C#,Web Config,Asp.net 4.0,我喜欢在运行时更新Web.config的AppSettings部分中定义的键/值。但是,我不想将它们实际保存到Web.config文件中 我有一个巨大的web应用程序,它由许多模块、DLL和源代码文件组成。web服务的数据库配置、加密密钥、用户名和密码等一系列关键信息都保存在AppSettings文件的web.config部分。最近的项目要求我将这些值移出web.config,并保存在安全的存储中 我已经在一个外部位置保护了这些值,并且可以在应用程序启动时读取它们 下面是示例代码 Global.

我喜欢在运行时更新
Web.config
AppSettings
部分中定义的键/值。但是,我不想将它们实际保存到
Web.config
文件中

我有一个巨大的web应用程序,它由许多模块、DLL和源代码文件组成。web服务的数据库配置、加密密钥、用户名和密码等一系列关键信息都保存在
AppSettings
文件的
web.config
部分。最近的项目要求我将这些值移出
web.config
,并保存在安全的存储中

我已经在一个外部位置保护了这些值,并且可以在应用程序启动时读取它们

下面是示例代码

Global.asax

public class Global: System.Web.HttpApplication {
    protected void Application_Start(object sender, EventArgs e) {
        Dictionary<string, string> secureConfig = new Dictionary<string,string>{};

        // --------------------------------------------------------------------
        // Here I read and decrypt keys and add them to secureConfig dictionary
        // To test assume the following line is a key stored in secure sotrage.
        //secureConfig = SecureConfig.LoadConfig();
        secureConfig.Add("ACriticalKey","VeryCriticalValue");
        // --------------------------------------------------------------------

        foreach (KeyValuePair<string, string> item in secureConfig) {
            ConfigurationManager.AppSettings.Add(item.Key, item.Value);
        }
    }
}
公共类全局:System.Web.HttpApplication{
受保护的无效应用程序\u启动(对象发送方,事件参数e){
Dictionary secureConfig=新字典{};
// --------------------------------------------------------------------
//在这里,我读取并解密密钥,并将它们添加到secureConfig字典中
//要进行测试,请假定以下行是存储在secure sotrage中的密钥。
//secureConfig=secureConfig.LoadConfig();
添加(“ACriticalKey”、“VeryCriticalValue”);
// --------------------------------------------------------------------
foreach(secureConfig中的KeyValuePair项){
ConfigurationManager.AppSettings.Add(item.Key、item.Value);
}
}
}
正如您可能注意到的,在由多个编程团队创建的大量代码中更改对
AppSettings
的引用以从我的
secureConfig字典中读取他们的设置是不可行的,另一方面,我不应该将这些值保存在
web.config
文件中,该文件可供web管理员和管理员使用操作员、系统管理员和云管理员

为了让程序员的生活更轻松,我想让他们在开发过程中将自己的值添加到
web.config
AppSettings
部分,但在部署过程中,这些值将被删除并放在安全存储中,但是,这些值应该可以透明地用于编程,因为它们仍然位于
AppSettings
部分

问题:如何在运行时向
AppSettings
添加值,以便程序可以使用
ConfigurationManager.AppSettings[“ACriticalKey”]
读取值,从而获得
“verycriticalvalvalue”
,而无需将其保存在Web.Config中

请注意:
ConfigurationManager.AppSettings.Add(item.Key,item.Value)向我提供
ConfigurationErrorsException
和消息
配置为只读。

请注意:一些设置最好能像以前一样留在
AppSettings

也许链接会有所帮助。它引用了2.0,但我相信该方法在4.0中仍然有效

此外,关于同一/类似主题的SO问题可能会引起兴趣


此外,在运行时修改web.config会导致每次应用程序池回收。不是想告诉你如何吮吸卵子,只是想为了任何人的潜在兴趣,我会记下它…谢谢。

你需要使用
WebConfigurationManager.OpenWebConfiguration()


多亏了恩伍,他把我引向了他的第一个链接,而他的第一个链接又把我发到了他的帖子“我设法找到了解决我问题的办法

上面提到的博客文章介绍了如何从另一个XML文件中读取设置,它同时适用于窗口应用程序和web应用程序(只需对配置文件名和路径进行一些修改)。尽管这篇博客是在2010年写的,但它仍然可以很好地使用.NET4

然而,当我要从一个安全设备读取配置时,我简化了这个类,下面是如何使用

如下图所示:

public class Global: System.Web.HttpApplication {

    //...

    #region protected void Application_Start(...)
    protected void Application_Start(object sender, EventArgs e) {
        Williablog.Core.Configuration.ConfigSystem .Install();

        //...

    }
    #endregion

    //...

}

我知道这是一个老问题,但我遇到了相同的问题,我发现Set与Add的工作方式相同,并且不会引发异常,因此只需将Add替换为Set,如下所示:

ConfigurationManager.AppSettings.Set(item.Key, item.Value);

谢谢您的回答,但我不想将值保存回Web.Config文件。另一方面,如果使用IIS设置,则此代码也不会工作,因为Web.Config是只读的,除非您更改Machine.Config,这在共享服务器中是不允许的。谢谢您的回答,不过本文建议您将值保存回配置文件(由于IIS的保护级别,这是不可能的,除非您修改machine.config)。您是对的,修改
Web.config
会回收不需要的应用程序池。a好的,我认为您不能这样做。我认为唯一的方法是通过创建一个具有AppSettings属性的SecureConfigurationManager类来添加另一层。AppSettings属性可以像ConfigurationManager的AppSettings一样调用(例如,
SecureConfigurationManager.AppSettings[]
),但其中有逻辑首先检查字典,如果找不到它,则返回到
ConfigurationManager.AppSettings[]
。我注意到这是一个代码更改(不是您所追求的)但可能影响较小这意味着您的开发人员不会注意到设置是否来自web.config中的
appSettings
,并且仍然可以愉快地将内容放在其中,而您的包装器在生产时会在设置不存在的情况下对此进行说明。然而,我可能已经偏离了主题,因此请反馈给me如果这不是您想要的-如果不是,我将删除此答案,因为它并没有真正为您的问题添加任何内容。抱歉,我不能提供更多帮助。实际上您的答案很有帮助。您共享的第一个链接引用了另一篇关于如何修改
ConfigurationManager
cla的文章
Williablog.Core.Configuration.ConfigSystem .Install();
public class Global: System.Web.HttpApplication {

    //...

    #region protected void Application_Start(...)
    protected void Application_Start(object sender, EventArgs e) {
        Williablog.Core.Configuration.ConfigSystem .Install();

        //...

    }
    #endregion

    //...

}
ConfigurationManager.AppSettings.Set(item.Key, item.Value);