使用 ConfigurationManager.RefreshSection 重新加载配置而不重新启动应用程序

Posted

技术标签:

【中文标题】使用 ConfigurationManager.RefreshSection 重新加载配置而不重新启动应用程序【英文标题】:Reloading configuration without restarting application using ConfigurationManager.RefreshSection 【发布时间】:2010-09-15 19:23:23 【问题描述】:

有没有人在网络应用程序中使用过这个?

无论我做什么,我的 appSettings 部分(使用 appSettings file=".\Site\site.config" 从 web.config 重定向)似乎都没有重新加载。

我是否注定要重新启动应用程序?我希望这种方法能引导我找到更高效的解决方案。

更新:

“重新加载”是指刷新 ConfigurationManager.AppSettings 而无需完全重新启动我的 ASP.NET 应用程序并且不必产生通常的启动延迟。

【问题讨论】:

【参考方案1】:

确保您将正确的 case sensitive 值传递给 RefreshSection,即

ConfigurationManager.RefreshSection("appSettings");

【讨论】:

你将如何刷新整个文件? 这行得通。只需正确拼写部分名称即可。例如:“connectionStrings”。 我知道这是一篇旧帖子,但仍然:RefreshSection 不是 WebConfigurationManager 类中的方法。所以我很想知道 ConfigurationManager.RefreshSection 是否也会刷新 web.config? @Shashi 更改 web.config 将重新启动您的网站,无论如何。因此,将该方法添加到 WebConfigurationManager 类是没有用的。 注意修改app.config不会影响被调试的程序。如果要在调试期间刷新值,则应更改 .vshost.exe.config 以查看更改。但是,它的工作原理与您单独运行应用程序时描述的一样。【参考方案2】:

在为您的 appSettings 使用外部配置文件时,这似乎是一个缺陷(可能是错误)。我已经尝试使用 configSource 属性,而 RefreshSection 根本不起作用,我假设在使用 file 属性时这是相同的。 如果您将 appSettings 移回 web.config RefreshSection 将完美运行,否则恐怕您注定要失败。

【讨论】:

我也注意到了。有什么解决办法吗? 我的应用程序(不是网络)也有同样的问题。我有一个名为“AdminSettings”的自定义部分,无论将其保存在外部文件中还是将其带回我的 app.config,我都无法在应用程序运行时读取更新的键/值。我认为这可能与部分名称有关,也许部分有一个完全限定的名称?我尝试了诸如“配置/设置”之类的东西,但没有奏效! ://【参考方案3】:

由于某种原因,ConfigurationManager.RefreshSection("appSettings") 不适合我。将 Web.Config 重新加载到 Configuration 对象中似乎可以正常工作。以下代码假定 Web.Config 文件位于执行 (bin) 文件夹下的一个目录。

ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
Uri uriAssemblyFolder = new Uri(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase));
string appPath = uriAssemblyFolder.LocalPath;
configMap.ExeConfigFilename = appPath + @"\..\" + "Web.config";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None); 

并且像这样使用:

string webConfigVariable = config.AppSettings.Settings["webConfigVariable"].Value;

【讨论】:

Web.config 更改不应该在 IIS 服务器的下一个请求中自动生效吗?【参考方案4】:

.RefreshSection() 在 appSettings 为外部时不起作用。

但是,您可以使用以下方法更改值:

ConfigurationManager.AppSettings.Set(key, value)

这不会改变文件上的设置,只会改变内存中加载的值。

因此,我没有使用 RefreshSection,而是执行了以下操作:

string configFile="path to your config file";
XmlDocument xml = new XmlDocument();
xml.Load(configFile);

foreach (XmlNode node in xml.SelectNodes("/appSettings/add"))

    string key = node.Attributes["key"].Value;
    string value= node.Attributes["value"].Value;
    ConfigurationManager.AppSettings.Set(key, value);

对 AppSettings.Get 的任何后续调用都将包含更新后的值。

appSettings 将随后更新,无需重新启动应用程序。

【讨论】:

【参考方案5】:

作为替代方案,您可以编写自己的ConfigSection 并设置restartOnExternalChanges="false"

然后,当阅读带有ConfigurationManager.GetSection("yourSection") 的部分时,设置将自动刷新而无需重新启动应用程序

您可以将设置实现为强类型或 NameValueCollection。

【讨论】:

【参考方案6】:

是的。你被 iis 重新启动卡住了。

asp.net 4.0 和 iis 7.5 的一个特性是删除了初始启动。

【讨论】:

【参考方案7】:

我不确定这在网络应用程序中是否可行,但它在桌面应用程序中有效。尝试使用 ConfigurationSettings 而不是 ConfigurationManager(它会因为使用过时的类而对你大喊大叫......),然后将所有数据读入一个类。当您希望刷新时,只需创建一个新实例并删除对旧实例的所有引用。我为什么这样做的理论(可能是错误的):当您在整个运行过程中不直接访问 app.config 文件时,应用程序会删除文件锁定。然后,可以在您不访问文件时进行编辑。

【讨论】:

【参考方案8】:

App.Config 设置在应用程序启动时缓存在内存中。出于这个原因,我认为您将无法在不重新启动应用程序的情况下更改这些设置。一种非常简单的替代方法是创建一个单独的简单 XML 配置文件,并自己处理加载/缓存/重新加载。

【讨论】:

那么msdn.microsoft.com/en-us/library/… 是干什么用的? 好问题 - 我不知道 :) @Terrapin:请尝试 KieranBenton 建议的 RefreshSection 方法,它有效。在这个 SO 线程中查看我的答案:***.com/questions/272097/… 不得不说:我还没有在网络应用程序中尝试过。我认为这应该会有所帮助:msdn.microsoft.com/en-us/library/…(您需要明确设置SectionInformation.RestartOnExternalChanges)编辑:刚刚注意到Meixger 已经提出了这个建议【参考方案9】:

要写,这样称呼它:

Dim config As System.Configuration.Configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~")

返回 AddOrUpdateAppSetting(config, "YourSettingKey", "YourValueForTheKey")

要读取并确保您获得的是文件中的值,而不是缓存中的值,请以这种方式读取:

Dim config As System.Configuration.Configuration = WebConfigurationManager.OpenWebConfiguration("~")
  Return config.AppSettings.Settings("TheKeyYouWantTheValue").Value

完整示例:

Protected Shared Function AddOrUpdateAppSetting( _
       ByVal Config As System.Configuration.Configuration _
     , ByVal TheKey As String _
     , ByVal TheValue As String _
     ) As Boolean</p>

    Dim retval As Boolean = True

    Dim Itm As System.Configuration.KeyValueConfigurationElement = _
        Config.AppSettings.Settings.Item(TheKey)
    If Itm Is Nothing Then
        If Config.AppSettings.Settings.IsReadOnly Then
        retval = False
        Else
        Config.AppSettings.Settings.Add(TheKey, TheValue)
        End If


    Else
        ' config.AppSettings.Settings(thekey).Value = thevalue
        If Itm.IsReadOnly Then
            retval = False
        Else
            Itm.Value = TheValue
        End If


    End If
    If retval Then
     Try
        Config.Save(ConfigurationSaveMode.Modified)

     Catch ex As Exception
        retval = False
     End Try

    End If

    Return retval

End Function

【讨论】:

标签上写着 C# not vb.net【参考方案10】:

您是否尝试将 AppSettings 存储在其自己的外部文件中?

来自 app.config/web.config:

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

appSettings.config:

<?xml version="1.0"?>
<appSettings>
  <add key="SomeKey" value="SomeValue" />
</appSettings>

对 appSettings.config 所做的更改应立即反映。 更多信息: http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource.aspx

【讨论】:

我相信 OP 已经在使用外部文件。他的问题涉及在没有应用程序(或应用程序域)重启的情况下反映外部文件中所做的更改 同意dotnetguy。他已经这样做了 - 这是他的问题 - 这样做并且无法即时刷新对其所做的更改。

以上是关于使用 ConfigurationManager.RefreshSection 重新加载配置而不重新启动应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)