使用 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不会影响被调试的程序。如果要在调试期间刷新值,则应更改在为您的 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有三种方式(不使用,动态使用,静态使用,默认是动态使用)