Custom Config section in App.config C# - c#

I'm a quite beginner with config sections in c#
I want to create a custom section in config file. What I've tried after googling is as the follows
Config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="MyCustomSections">
<section name="CustomSection" type="CustomSectionTest.CustomSection,CustomSection"/>
</sectionGroup>
</configSections>
<MyCustomSections>
<CustomSection key="Default"/>
</MyCustomSections>
</configuration>
CustomSection.cs
namespace CustomSectionTest
{
public class CustomSection : ConfigurationSection
{
[ConfigurationProperty("key", DefaultValue="Default", IsRequired = true)]
[StringValidator(InvalidCharacters = "~!##$%^&*()[]{}/;'\"|\\", MinLength = 1, MaxLength = 60)]
public String Key
{
get { return this["key"].ToString(); }
set { this["key"] = value; }
}
}
}
When I use this code to retrieve Section I get an error saying configuration error.
var cf = (CustomSection)System.Configuration.ConfigurationManager.GetSection("CustomSection");
What am I missing?
Thanks.
Edit
What I need ultimately is
<CustomConfigSettings>
<Setting id="1">
<add key="Name" value="N"/>
<add key="Type" value="D"/>
</Setting>
<Setting id="2">
<add key="Name" value="O"/>
<add key="Type" value="E"/>
</Setting>
<Setting id="3">
<add key="Name" value="P"/>
<add key="Type" value="F"/>
</Setting>
</CustomConfigSettings>

App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="customAppSettingsGroup">
<section name="customAppSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</sectionGroup>
</configSections>
<customAppSettingsGroup>
<customAppSettings>
<add key="KeyOne" value="ValueOne"/>
<add key="KeyTwo" value="ValueTwo"/>
</customAppSettings>
</customAppSettingsGroup>
</configuration>
Usage:
NameValueCollection settings =
ConfigurationManager.GetSection("customAppSettingsGroup/customAppSettings")
as System.Collections.Specialized.NameValueCollection;
if (settings != null)
{
foreach (string key in settings.AllKeys)
{
Response.Write(key + ": " + settings[key] + "<br />");
}
}

Try using:
var cf = (CustomSection)System.Configuration.ConfigurationManager.GetSection("MyCustomSections/CustomSection");
You need both the name of the section group and the custom section.

Highlight ConfigurationSection press F1,
You will see that the implementation on the MSDN website overrides a property called "Properties" which returns a "ConfigurationPropertyCollection", as your properties have a matching attribute of that type you should be able to populate this collection with your properties if not wrap them in the same way the MS guys have.

Related

Missing entries in user.config after decryption/encryption

I like to store a username and password to the user.config in my C# .net5 program. I don't want to store the password direct and I decided to decrypt the userSettings section.
After decryption parts of the file are missing.
Orginal user.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" >
<section name="FileUploader.Properties.Settings" type="System.Configuration.ClientSettingsSection, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToLocalUser" overrideModeDefault="Allow" restartOnExternalChanges="true" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<FileUploader.Properties.Settings>
<setting name="UserName" serializeAs="String">
<value>user</value>
</setting>
<setting name="Password" serializeAs="String">
<value>xyz</value>
</setting>
</FileUploader.Properties.Settings>
</userSettings>
</configuration>
After encryption:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" >
<section name="FileUploader.Properties.Settings" type="System.Configuration.ClientSettingsSection, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToLocalUser" overrideModeDefault="Allow" restartOnExternalChanges="true" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<FileUploader.Properties.Settings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA4LmAfRMCHUeURwT1gTPd8AQAAAACAAAAAAAQZgAAAAEAACAAAADnR+uFolwsH4gkWI6vd46HNUxBv7ZfrQJmHe0q/zz8jAAAAAAOgAAAAAIAACAAAABlvfcY6M7JdG2dKIXO7cUUO9ui3Nou40CjMolKyJW7zgACAAAL5H+KJFPGoyugYYFDkZsV7GjXoaO+r8/z01/OiqVYXw80dCUIKje2g0tgizNrB/rAUmSg/uDPBx1yj3TAJ5aXf+fRxJaspf1jjr+QIaSJShnpy1sEjjpbUUn9+BVCYSJH8d4Ysj2JP1wvM5mgFBlFUcCLhHO+FputK3XpihAZCXeOddjNw2xYIQu4pmenLBiW6+fRUpINmNan/exQvHOWfwXuoZvqUli1hv+29qTuh/eJuPJQoyQSKrZ1A6Ie8aG2dsgQDvnVFEkt8cChkTn/TIc2Dk1uSDrsIYj/Ah8g1T5bE3PvWAYv67vtEfKbwBrqig+3HOSltZayVWyd2Y7iDS15Qk763ipiaBM64zhs/g4koQWpH1kAkfqgW3ibYAJEsk1a/K0Dd1Q2muxo0fsk1DfNYJIhFS8eAIuABlF6NAF5AT5hYyIOWVGjaquEP/aqzepCjEwkoLgD003qMISK7W6EAugSbWCRTwcMcKxZD3tHTmNLzZk+g8C7XpaWOk0xyODi5+mVXI8zg7NIGYo34JPado8l0p0Qd0gx15PwtZNHj0k9o6rieTgWjJEqf52ng70DNySsSX3jfyW91ArslcMLqO1qpbSFuIt0LeIswSxoR/etNM+GoGUjRW7t1OKGLcV5Wi8k0QdheXhxo6Hvq2/nv9iFYJxqgwoN6v1N0kAAAAACcCtrS9KBGCutdHdYddlimN5cPb8+X/snuKEgu63fi4TE2VSei4R0WqjeC22JIFn3HqPIzWb9Kd9pPDJCWQz7</CipherValue>
</CipherData>
</EncryptedData>
</FileUploader.Properties.Settings>
</userSettings>
</configuration>
After decryption:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" >
<section name="FileUploader.Properties.Settings" type="System.Configuration.ClientSettingsSection, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" allowLocation="true" allowDefinition="Everywhere" allowExeDefinition="MachineToLocalUser" overrideModeDefault="Allow" restartOnExternalChanges="true" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<FileUploader.Properties.Settings>
<setting name="" serializeAs="String">
<value>xyz</value>
</setting>
</FileUploader.Properties.Settings>
</userSettings>
</configuration>
There is only the last entry and the name of the entry is missing. If I switch the order in the original file, I get "user" as the value.
The code to decrypt/encrypt (more or less a copy of an msdn example):
private void ProtectSettings()
{
// Get the application configuration file.
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);
// Define the Rsa provider name.
string provider = "DataProtectionConfigurationProvider";
string section = "userSettings/" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Properties.Settings";
// Get the section to protect.
ConfigurationSection connStrings = config.GetSection(section);
if (connStrings != null)
{
if (!connStrings.SectionInformation.IsProtected)
{
if (!connStrings.ElementInformation.IsLocked)
{
// Protect the section.
connStrings.SectionInformation.ProtectSection(provider);
connStrings.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
Debug.WriteLine("Section {0} is now protected by {1}",
connStrings.SectionInformation.Name,
connStrings.SectionInformation.ProtectionProvider.Name);
}
else
Debug.WriteLine(
"Can't protect, section {0} is locked",
connStrings.SectionInformation.Name);
}
else
Debug.WriteLine(
"Section {0} is already protected by {1}",
connStrings.SectionInformation.Name,
connStrings.SectionInformation.ProtectionProvider.Name);
}
else
Debug.WriteLine("Can't get the section {0}", section);
}
private static void UnProtectSettings()
{
// Get the application configuration file.
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);
string section = "userSettings/" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Properties.Settings";
// Get the section to unprotect.
ConfigurationSection connStrings = config.GetSection(section);
if (connStrings != null)
{
if (connStrings.SectionInformation.IsProtected)
{
if (!connStrings.ElementInformation.IsLocked)
{
// Unprotect the section.
connStrings.SectionInformation.UnprotectSection();
connStrings.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
Debug.WriteLine("Section {0} is now unprotected.",
connStrings.SectionInformation.Name);
}
else
Debug.WriteLine(
"Can't unprotect, section {0} is locked",
connStrings.SectionInformation.Name);
}
else
Debug.WriteLine(
"Section {0} is already unprotected.",
connStrings.SectionInformation.Name);
}
else
Debug.WriteLine("Can't get the section {0}", section);
}
After playing around with this for a while, I discovered that the issue comes from the ConfigurationSaveMode.Full option.
In both ProtectSettings() and UnProtectSettings(), instead of
connStrings.SectionInformation.ForceSave = true;
config.Save(ConfigurationSaveMode.Full);
simply use:
config.Save();
I have no idea why that option leads to unwanted behavior.

Having Issues reading / parsing Xml doc

I have a Xml doc similar (edited for here) to this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="WebApptNotificationService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<connectionStrings>
removed for questions
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="C:\test\"/>
</smtp>
</mailSettings>
<mailSettings>
<smtp from="xxxxx#xxxxxx.com">
<network host="mail.xxxxxxxx.com" enableSsl="true" password="xxxxxx" port="xxx" userName="xx#xxxxxxxx.com"/>
</smtp>
<smtp from="No.Reply#xxxxxxxxxx.org">
<network host="1stmsmail.xxxx.local" enableSsl="true" password="xxxxxxx" port="587" userName="ouruser"/>
</smtp>
</mailSettings>
</system.net>
<applicationSettings>
<WebApptNotificationService.Properties.Settings>
<setting name="ConfirmationInterval" serializeAs="String">
<value>60000</value>
</setting>
<setting name="EmailFromName" serializeAs="String">
<value>Test</value>
</setting>
<setting name="EmailFromAddress" serializeAs="String">
<value>mobile#xxxxx.com</value>
</setting>
<setting name="DaysBeforeReminder" serializeAs="String">
<value>2</value>
</setting>
<setting name="MinTextMinute" serializeAs="String">
<value>480</value>
</setting>
<setting name="MaxTextMinute" serializeAs="String">
<value>1200</value>
</setting>
</WebApptNotificationService.Properties.Settings>
</applicationSettings>
</configuration>
I am trying to read the values for using the following code:
private string parseXML(string name)
{
string returnVal = string.Empty;
XmlDocument xmlDoc = xmlFile.SettingXML;
//returnVal = xmlDoc.GetElementsByTagName(name).ToString();
XmlNode node = xmlDoc.SelectSingleNode("//configuration//applicationSettings//WebApptNotificationService.Properties.Settings//setting");
MessageBox.Show(node.ToString());
//returnVal = xmlDoc.DocumentElement.Name.(x => x.Element("Author"));
return returnVal;
}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim xdoc As XDocument = XDocument.Load(FILENAME)
Dim versions As IEnumerable(Of XElement) = xdoc.Descendants("Version")
For Each version As XElement In versions
For Each trunk As XElement In version.Elements("Trunk")
Console.WriteLine(CType(trunk, String))
ComboBox1.Items.Add(CType(trunk, String))
Next trunk
For Each xEle As XElement In version.Elements("Branch")
Console.WriteLine(CType(xEle, String))
ComboBox2.Items.Add(CType(xEle, String))
Next xEle
Next version
End Sub
Now xmlFile.SettingXML is a class that is created from a config file. It is stored as a class. I want to get the values from the settings name, based on the name passed in. It appears though as if I am failing miserably. If someone could please point me to the correct way to handle this it would be very much appreciated.
Edit: Failing miserably as was pointed out doesn't describe this issue. Right now I am getting System.Xml.XmlElement in the Messagebox.
As you say Right now I am getting System.Xml.XmlElement in the Messagebox try use MessageBox.Show(node.InnerText) this wil get the inner text of the settings element (node object). If you display your node object in the message box it will call the ToString method on the object whits is System.Xml.XmlElement.
Whit XDocument you easily can do this:
static void Main(string[] args)
{
string value = ParseXML("EmailFromAddress");
Console.WriteLine(value);
}
private static string ParseXML(string name)
{
// Load Document use 'XDocument.Parse' if you want to load the document from string
XDocument xmlDoc = XDocument.Load("C:\\t\\2.txt");
// Select element setting where name attribute is equal to name
var node = xmlDoc
.Descendants("WebApptNotificationService.Properties.Settings")
.Elements("setting")
.FirstOrDefault(x => (string) x.Attribute("name") == name);
return node.Value;
}

ConfigurationSection won't convert to NameValueCollection

I have this Q1.config file in my Console Application (.NET 4.5.2)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="globalKey" value="globalValue" />
</appSettings>
<configSections>
<section name="validations" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<validations>
<add key="validationKey" value="validationValue"/>
</validations>
</configuration>
I'm reading it like this
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap { ExeConfigFilename = "Q1.config" };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
ConfigurationSection validationSettings = config.GetSection("validations");
This works fine:
string globalValue = config.AppSettings.Settings["globalKey"].Value;
But how do I get my "validationKey"? I tried these but they don't work:
validationSettings["validationKey"]
validationSettings.Settings["validationKey"]
(config.GetSection("validations") as NameValueCollection)["validationKey"]
With the answer from #Karthik I ran into an issue... if I use ConfigurationManager.GetSection() I only get null. To get the section I have to use the config object returned by OpenMappedExeConfiguration. However, GetSection() in config isn't of type object as in ConfigurationManager, but DefaultSection from which I can't read the key value pairs, nor can I cast it to NameValueCollection. Browsing on the web I found this article with a solution that worked for me.
Basically extract the XML from the section and parse it manually with an XmlDoc.
public static NameValueCollection GetSectionSettings(string sectionToRead, string configPath)
{
if (!File.Exists(configPath)) { throw new ArgumentException($"File not found: {configPath}", nameof(configPath)); }
var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = configPath };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
string settingsXml = config.GetSection(sectionToRead).SectionInformation.GetRawXml();
XmlDocument settingsXmlDoc = new XmlDocument();
settingsXmlDoc.Load(new StringReader(settingsXml));
NameValueSectionHandler handler = new NameValueSectionHandler();
return handler.Create(null, null, settingsXmlDoc.DocumentElement) as NameValueCollection;
}
Here you go
Your XML configuration
<configuration>
<configSections>
<section name="validations" type="System.Configuration.AppSettingsSection" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="globalKey" value="globalValue" />
</appSettings>
<validations>
<add key="validationKey" value="validationValue"/>
</validations>
</configuration>
And you can get these values in C# using
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap { ExeConfigFilename = "Q1.config" };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
NameValueCollection validationSettings = (NameValueCollection)ConfigurationManager.GetSection("validations");
string globalValue = validationSettings[0];
I've used an index here validationSettings[0] to access the value. You can use your key to get the value
Thanks

Memcache - Cached Data is always null

Below is my try to use Memcache in a console application.
App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="enyim.com"/>
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection,Enyim.Caching"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<enyim.com>
<memcached protocol="Binary">
<severs>
<add address="127.0.0.1" port="11211"/>
</severs>
</memcached>
</enyim.com>
</configuration>
C#
static void Main(string[] args)
{
DateTime dt = DateTime.Now;
try
{
using (MemcachedClient memcache = new MemcachedClient())
{
string cachedTime = memcache.Get<string>("CachedTime");
if (cachedTime == null)
{
memcache.Store(Enyim.Caching.Memcached.StoreMode.Set, "CachedTime", DateTime.Now.ToString());
cachedTime = memcache.Get<string>("CachedTime");
}
Console.WriteLine(cachedTime);
Console.WriteLine(dt);
}
}
catch (Exception ex)
{
}
}
Every time the value of cachedDate is NULL
Change App.Config to the following and it should work:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<enyim.com>
<memcached>
<servers>
<add address="127.0.0.1" port="11211" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>
</configuration>

Write appSettings in external file

I have a config file app.exe.config and appSettings section has something like this:
<configuration>
<appSettings configSource="app.file.config" />
</configuration>
app.file.config file has something like this:
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="var1" value="value 1" />
<add key="var2" value="value 2" />
<add key="var3" value="value 3" />
</appSettings>
I need to edit var1, var2 and var3 at runtime and I have code like this:
Configuration config = ConfigurationManager.OpenExeConfiguration("...path\app.exe);
config.AppSettings.SectionInformation.ConfigSource = "app.file.config";
config.AppSettings.Settings["var1"].Value = "value 11";
config.AppSettings.Settings["var2"].Value = "value 22";
config.AppSettings.Settings["var3"].Value = "value 33";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
When I run config.Save.... the file app.file.config has a appSettings node with an attribute "file". This attribute has the value to app.file.config
<appSettings file="app.file.config">
<add key="var1" value="value 1" />
<add key="var2" value="value 2" />
<add key="var3" value="value 3" />
</appSettings>
Now, if I try to load the config file, I have an exception with message "Unrecognized attribute 'file'. Note that attribute names are case-sensitive." in app.file.config.
If I delete the file attribute manually, the configuration file is loaded properly.
Any ideas?
How can avoid to write file attribute when I save config files.
Thanks
using an external config file is transparent for the application,
this part is o.k
</configuration>
<appSettings configSource="app.file.config" />
</configuration>
and also this:
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="var1" value="value 1" />
<add key="var2" value="value 2" />
<add key="var3" value="value 3" />
</appSettings>
change your code to be like this:
Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
config.AppSettings.Settings["var1"].Value = "value 11";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
referring an external configuration file is transparent to the application,
so you don't have to call it directly. you can use the default appSetting section in the configuration manager.
Good luck
A more complete answer to prevent confusion:
Setup:
Commandline project called 'app'
app.exe.config file, App.config:
<appSettings file="App.Settings.config"></appSettings>
App.Settings.config file with 'Copy to Output Directory'= 'Copy Always'
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="test" value="OVERRIDDEN"/>
</appSettings>
Program.cs:
static void Main(string[] args)
{
try
{
Console.WriteLine("Local Config sections");
var exepath = (new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase)).LocalPath;
Configuration config = ConfigurationManager.OpenExeConfiguration(exepath);
config.AppSettings.SectionInformation.ConfigSource = "App.Settings.config";
Console.WriteLine("BEFORE[test]=" + config.AppSettings.Settings["test"].Value);
Console.WriteLine($"BEFORE[testExternalOnly]={config.AppSettings.Settings["testExternalOnly"]?.Value}");
//to avoid: Error CS0266
//Explicitly cast 'System.Configuration.AppSettingsSection'
AppSettingsSection myAppSettings = (AppSettingsSection)config.GetSection("appSettings");
myAppSettings.Settings["test"].Value = "NEW";
if (!myAppSettings.Settings.AllKeys.Contains("testExternalOnly"))
myAppSettings.Settings.Add("testExternalOnly", "NEWEXTERNAL");
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
//Read updated config
Console.WriteLine("AFTER[test]=" + config.AppSettings.Settings["test"].Value);
Console.WriteLine("AFTER[testExternalOnly]=" + config.AppSettings.Settings["testExternalOnly"].Value);
Console.WriteLine("AFTER CONFIG EXTERNAL FILE: " + System.IO.File.ReadAllText("App.Settings.config"));
Console.WriteLine("AFTER CONFIG FILE: " + System.IO.File.ReadAllText(System.AppDomain.CurrentDomain.FriendlyName + ".config"));
//Shut current config
config = null;
//Open config
config = ConfigurationManager.OpenExeConfiguration(exepath);
config.AppSettings.SectionInformation.ConfigSource = "App.Settings.config";
Console.WriteLine("AFTER[test]=" + config.AppSettings.Settings["test"].Value);
Console.WriteLine("AFTER[testExternalOnly]=" + config.AppSettings.Settings["testExternalOnly"].Value);
Console.WriteLine("AFTER CONFIG EXTERNAL FILE: " + System.IO.File.ReadAllText("App.Settings.config"));
Console.WriteLine("AFTER CONFIG FILE: " + System.IO.File.ReadAllText(System.AppDomain.CurrentDomain.FriendlyName + ".config"));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("press the ENTER key to end");
Console.ReadLine();
}
This will result in App.Settings.config file updated to be on the filesystem as:
<?xml version="1.0" encoding="utf-8"?>
<appSettings>
<add key="test" value="NEW" />
<add key="testExternalOnly" value="NEWEXTERNAL" />
</appSettings>
Finally, I have found a solution.
The solution is to declare the config file as this:
<appSettings configSource="app.file.config">
<add key="var1" value="value 1" />
<add key="var2" value="value 2" />
<add key="var3" value="value 3" />
</appSettings>
And from code
Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
AppSettingsSection myAppSettings = config.GetSection("appSettings")
myAppSettings.Settings["var1"].Value = "value 11";
config.Save(ConfigurationSaveMode.Modified);
Note that I use
GetSection("appSettings")
instead of
config.AppSettings.Settings
Thanks to all that help people in StackOverflow.

Categories