如何在运行时修改web.config appSettings?


84

我对如何在运行时修改web.config appSettings值感到困惑。例如,我有以下appSettings部分:

<appSettings>
  <add key="productspagedesc" value="TODO: Edit this default message" />
  <add key="servicespagedesc" value="TODO: Edit this default message" />
  <add key="contactspagedesc" value="TODO: Edit this default message" />
  <add key="aboutpagedesc" value="TODO: Edit this default message" />
  <add key="homepagedesc" value="TODO: Edit this default message" />
 </appSettings>

假设我想在运行时修改“ homepagedesc”键。我尝试了ConfigurationManager和WebConfigurationManager静态类,但设置为“只读”。如何在运行时修改appSettings值?

更新:好的,所以我在5年后。我想指出,经验告诉我,我们不应将任何在运行时有意编辑的配置放在web.config文件中,而应将其放在单独的XML文件中,如以下一位用户所评论。这将不需要任何web.config文件的编辑即可重新启动应用程序,这将导致生气的用户致电给您。


这是一个很好的链接,很好地解释了有关在运行时修改web.config及其对应用程序的影响。http://aspdotnethacker.blogspot.com/2010/05/modify-webconfig-file-at-runtime.html

5
@ user330004您提供的链接不再有效
McArthey 2013年

只需几秒钟即可找到存档版本
斯图尔特(Stuartd)

Answers:


84

您需要使用WebConfigurationManager.OpenWebConfiguration():例如:

Dim myConfiguration As Configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~")
myConfiguration.ConnectionStrings.ConnectionStrings("myDatabaseName").ConnectionString = txtConnectionString.Text
myConfiguration.AppSettings.Settings.Item("myKey").Value = txtmyKey.Text
myConfiguration.Save()

我认为您可能还需要在machine.config中设置AllowLocation。这是一个布尔值,指示是否可以使用元素配置各个页面。如果“ allowLocation”为false,则不能在单个元素中进行配置。

最后,如果您在IIS中运行应用程序并从Visual Studio运行测试示例,则将有所不同。ASP.NET进程标识是IIS帐户,ASPNET或NETWORK SERVICES(取决于IIS版本)。

可能需要授予ASPNET或网络服务修改web.config所在的文件夹上的访问权限。


1
感谢您的回应米奇。你回答了我的问题。我所做的是我以管理员身份运行VS 2008,并且一切正常。
jerbersoft

也许对其他人显而易见(对我而言不是),这个答案以及在功能上相同的Amin实际上覆盖了您的物理web.config文件,而不仅仅是覆盖特定运行实例的内存设置。
k3davis

24

更改web.config通常会导致应用程序重新启动。

如果您确实需要应用程序来编辑其自己的设置,则应考虑使用其他方法,例如对设置进行数据库设置或使用可编辑的设置创建xml文件。


1
嗨,谢谢您的回复。但是,此“配置”类具有“保存”功能。您是否真的必须重新启动应用程序才能使新设置生效?
jerbersoft

4
更改web.config会自动触发应用程序重新启动。
Mike Cole

1
不建议动态更改web.config。我希望将值存储在(xml)文件中。
迪帕克·米什拉

有人可以解释为什么重新启动应用程序很不好,许多人建议将属性移到另一个文件吗?

1
@Ben-我知道已经过去了几个月,但是以防万一-重新启动应用程序意味着在重新启动点登录到您的应用程序的任何人都将自动注销,并且很可能会遇到错误。(尽管存在各种情况,例如Web场...)。愤怒的用户联系支持人员,支持您联系等等,等等...
Fetchez la vache

24

而且,如果您希望避免重新启动应用程序,则可以移出以下appSettings部分:

<appSettings configSource="Config\appSettings.config"/>

到一个单独的文件。并与ConfigurationSaveMode.Minimal

var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
config.Save(ConfigurationSaveMode.Minimal);

您可以继续将该appSettings部分用作各种设置的存储,而不会导致应用程序重新启动,也不需要使用格式与普通appSettings部分不同的文件。


21

2012 对于这种情况,这是一个更好的解决方案(已通过Visual Studio 2008测试):

Configuration config = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
config.AppSettings.Settings.Remove("MyVariable");
config.AppSettings.Settings.Add("MyVariable", "MyValue");
config.Save();

更新2018 =>
在vs 2015中测试-Asp.net MVC5

var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
config.AppSettings.Settings["MyVariable"].Value = "MyValue";
config.Save();

如果您需要检查元素是否存在,请使用以下代码:

var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
if (config.AppSettings.Settings["MyVariable"] != null)
{
config.AppSettings.Settings["MyVariable"].Value = "MyValue";
}
else { config.AppSettings.Settings.Add("MyVariable", "MyValue"); }
config.Save();

您能否详细说明为什么会更好?我知道configSection的东西有时有点棘手。
julealgon

1
此代码更小,更易于理解!至少对于我来说。
Amin Ghaderi

3
哦,那是因为当时的个人品味,我实际上认为这在逻辑上有所不同。在这种情况下,我确实非常反对,尽管实际上有很多原因:首先是因为您必须两次指定相同的键,其次是因为您所做的操作在语义上与实际需要的有所不同('update'与'remove-> add')和第三,因为代码实际上更长(不确定在这里为什么要这么做)并且容易出错。另外,如果由于某种原因两次调用之间代码失败了怎么办?我认为您的应用程序从此被破坏了。
julealgon

2
此代码将删除对MyVariable的任何注释。
blagus

对,就是这样 !此代码将所有变量重写,但是可以正常工作。但是当您使用注释代码时,我不建议您使用它。谢谢。
阿敏·加德里

13

我知道这个问题很旧,但是我想结合我的实际经验,根据ASP.NET \ IIS世界中的当前状况发布答案。

我最近在公司领导了一个项目,我想在一个中央位置整合和管理web.config文件中的所有appSettings和connectionStrings设置。由于项目的成熟度和稳定性,我想采用一种方法,将我们的配置设置存储在ZooKeeper中。更不用说ZooKeeper是设计使然的配置和集群管理应用程序。

项目目标非常简单;

  1. 获取ASP.NET与ZooKeeper进行通信
  2. 在Global.asax中,Application_Start-从ZooKeeper中提取web.config设置。

通过了使ASP.NET与ZooKeeper进行通信的技术性工作之后,我迅速找到了以下代码,并碰壁了;

ConfigurationManager.AppSettings.Add(key_name, data_value)

自从我想将新设置添加到appSettings集合以来,该声明具有最合理的意义。但是,正如原始海报(以及许多其他海报)所述,此代码调用返回一个错误,指出该集合是只读的。

在进行了一些研究并且看到人们解决该问题的所有不同疯狂方式之后,我感到非常沮丧。我没有放弃或解决似乎不太理想的情况,而是决定深入研究,看看我是否缺少某些东西。

经过一番尝试和错误,我发现下面的代码可以完全满足我的要求。

ConfigurationManager.AppSettings.Set(key_name, data_value)

现在,使用这一行代码,我可以从ZooKeeper的Application_Start中加载所有85个appSettings项。

关于有关触发IIS回收的web.config更改的一般性声明,我编辑了以下appPool设置以监视幕后情况。

appPool-->Advanced Settings-->Recycling-->Disable Recycling for Configuration Changes = False
appPool-->Advanced Settings-->Recycling-->Generate Recycle Event Log Entry-->[For Each Setting] = True

使用这些设置组合,如果此过程导致appPool回收,则应该记录一个事件日志条目,而没有记录。

这使我得出结论,从集中式存储介质加载应用程序设置是可能的,而且确实是安全的。

我应该提到我在Windows 7上使用IIS7.5。该代码将被部署到Win2012上的IIS8。如果该答案有任何更改,我将相应地更新此答案。


这可能只是节省了我几个小时。非常感谢!
德鲁·德拉诺

4

谁直接喜欢这一点,

在您的配置中

    <appSettings>

    <add key="Conf_id" value="71" />

  </appSettings>

在您的代码中(C#)

///SET
    ConfigurationManager.AppSettings.Set("Conf_id", "whateveryourvalue");
      ///GET              
    string conf = ConfigurationManager.AppSettings.Get("Conf_id").ToString();

0

试试这个:

using System;
using System.Configuration;
using System.Web.Configuration;

namespace SampleApplication.WebConfig
{
    public partial class webConfigFile : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Helps to open the Root level web.config file.
            Configuration webConfigApp = WebConfigurationManager.OpenWebConfiguration("~");
            //Modifying the AppKey from AppValue to AppValue1
            webConfigApp.AppSettings.Settings["ConnectionString"].Value = "ConnectionString";
            //Save the Modified settings of AppSettings.
            webConfigApp.Save();
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.