web.config や app.config にある、「applicationSettings」。
このapplicationSettings で定義されている各Section毎のvalue値を書き換えるツールを作成したい場合、
他のWebサイトで紹介しているやり方だけでは、更新されないことがあるので、注意書きという形で
サンプルをご紹介します。
■書き換え前のconfig ファイル
<applicationSettings>
<MyApp.My.MySettings>
<setting name="WebSiteUrl" serializeAs="String">
<value>あいうえお</value>
</setting>
</MyApp.My.MySettings>
</applicationSettings>
■書き換え後のconfigファイルのイメージ
<applicationSettings>
<MyApp.My.MySettings>
<setting name="WebSiteUrl" serializeAs="String">
<value>http://techbank.jp/mymio/</value>
</setting>
</MyApp.My.MySettings>
</applicationSettings>
■実行サンプル(VB)
Imports System.Configuration
Imports System.Web.Configuration
Imports System.IO
Class MyClass1
Public Sub UpdateApplicationConfig()
' Web.Config の内容をConfigurationクラスにMapする
Dim configFile As New ExeConfigurationFileMap()
configFile.ExeConfigFilename = configFilePath
Dim config As Configuration = _
ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None)
' applicationSettings タグで定義されている構成(セクション)を取得する
Dim clientSettings As ClientSettingsSection = _
CType(config.GetSection("applicationSettings/MyApp.My.MySettings"), ClientSettingsSection)
Dim appSettings As SettingElementCollection = clientSettings.Settings
' valueタグに定義されている値を更新
#If 1 Then
' ForceSaveをTrueにすると、value値を更新することができる。
clientSettings.SectionInformation.ForceSave = True
appSettings.Get("WebSiteUrl").Value.ValueXml.InnerText = "http://techbank.jp/mymio/"
#Else
' ForceSaveプロパティの存在を知らないと、保存できないと嘆く羽目になる。
' そして、一旦Sectionを消して、新たな値を設定したSectionを追加する処理を記述する馬鹿らしいことをやる羽目になる・・・
Dim node As Xml.XmlNode = appSettings.Get("WebSiteUrl").Value.ValueXml.Clone
appSettings.Remove(appSettings.Get("WebSiteUrl"))
config.Save(ConfigurationSaveMode.Full)
Dim se As New SettingElement("WebSiteUrl", SettingsSerializeAs.String)
node.InnerText = "http://techbank.jp/mymio/"
se.Value.ValueXml = node
appSettings.Add(se)
#End If
config.Save(ConfigurationSaveMode.Full)
End Sub
End Class
■実行サンプル(C#)
using System.Configuration
using System.Web.Configuration
using System.IO
class MyClass1
{
public void UpdateApplicationConfig()
{
// Web.Config の内容をConfigurationクラスにMapする
ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename = configFilePath;
Configuration config =
ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
// applicationSettings タグで定義されている構成(セクション)を取得する
ClientSettingsSection clientSettings =
(ClientSettingsSection)config.GetSection("applicationSettings/MyApp.My.MySettings");
SettingElementCollection appSettings = clientSettings.Settings;
// valueタグに定義されている値を更新
#if 1
// ForceSaveをTrueにすると、value値を更新することができる。
clientSettings.SectionInformation.ForceSave = true;
appSettings.Get("WebSiteUrl").Value.ValueXml.InnerText = "http://techbank.jp/mymio/";
#elif
// ForceSaveプロパティの存在を知らないと、保存できないと嘆く羽目になる。
// そして、一旦Sectionを消して、新たな値を設定したSectionを追加する処理を記述する馬鹿らしいことをやる羽目になる・・・
Xml.XmlNode node = appSettings.Get("WebSiteUrl").Value.ValueXml.Clone;
appSettings.Remove(appSettings.Get("WebSiteUrl"));
config.Save(ConfigurationSaveMode.Full);
SettingElement se = new SettingElement("WebSiteUrl", SettingsSerializeAs.String);
node.InnerText = "http://techbank.jp/mymio/";
se.Value.ValueXml = node;
appSettings.Add(se);
#endif
config.Save(ConfigurationSaveMode.Full);
}
}
私が知らないだけだったというのもあるんですが、私の環境だと、
System.Configuration.SectionInformation.ForceSaveプロパティが既定でFalseになっているため、
System.Configuration.SectionInformation.ForceSaveプロパティをTrueにしてあげないと、
applicationSettings で定義されているSectionValue値を保存できなかったようです。
(更新はできるが保存できないという状況でした)
他のWebSiteを見ると、System.Configuration.SectionInformation.ForceSave プロパティを意識せず、
そのまま値を書き換えてSaveするサンプルを公開しているところが多かったため、
先日からずっとハマってしまったというわけです。
System.Configuration.SectionInformation.ForceSave プロパティの存在を知らないと、
上記サンプルの #Else ( C#だと、#elif )で記述したような、Section自体を削除/追加 で反映する馬鹿なコードを
書く羽目になりますので、くれぐれもご注意を。
知らないというのは、ある意味怖いですね orz
.NET を使った開発経験が、techbank.jp メンバーの皆様から比べても、かなり浅い方なので、
些細なことを見落としがちだなぁと、つくづく反省しまった今日この頃でした。