Note: I am new to ConfigurationManager and .NET in general.
I have:
static void Main(string[] args) {
//...
String path = ConfigurationManager.AppSettings["training_path"];
StreamReader sr = new StreamReader(path) // path always null
}
I added...
Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
...to the top of main, and it outputs the expected default configuration file.
The configuration file looks like 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="xgboost_format.Application" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<applicationSettings>
<myApp.Application>
<setting name="training_path" serializeAs="String">
<value>C:\test.csv</value>
</setting>
</myApp.Application>
</applicationSettings>
</configuration>
The issue is that the path setting is always null. I get a System.ArgumentNullException when calling new StreamReader(path).
How can I access the settings?
You can do it with (double-check the namespace is matching to whatever you have in your application):
String path = myApp.Application.Properties.Settings.Default.path;
You can also read Using Application Settings and User Settings which goes into more details about design-time settings.
Try this -
<appSettings>
<add key="training_path" value="C:\test.csv" />
</appSettings>
Related
I have the following code structure:
xUnit tests
These use features from my.dll
The my.dll uses a third party logger.dll
If I use the my.dll outside of xUnit's testserver.dll, then I can just add a my.dll.config with the following contents:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="Thirdparty.Logger.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</sectionGroup>
</configSections>
<assemblySettings>
<add key="Hostname" value="127.0.0.1"/>
<add key="Port" value="1234"/>
</assemblySettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<applicationSettings>
<Thirdparty.Logger.Properties.Settings>
<setting name="LogPath" serializeAs="String">
<value>C:\log\dir</value>
</setting>
</Thirdparty.Logger.Properties.Settings>
</applicationSettings>
</configuration>
And within my.dll's constructor, I can read them like follows, which works just fine.
AssemblySettings settings = new AssemblySettings();
var host = settings["Hostname"];
var port = settings["Port"];
Also the LogPath is passed on to logger.dll, which is closed source to me, but the logger.dll can definitely read the value passed on as LogPath.
Now, I have been successfully able to pass on the logger.dll's settings through xUnit as well using a testserver.dll.config file, which looks like follows:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="Thirdparty.Logger.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
<section name="MyDll.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<applicationSettings>
<Thirdparty.Logger.Properties.Settings>
<setting name="LogPath" serializeAs="String">
<value>C:\log\dir</value>
</setting>
</Thirdparty.Logger.Properties.Settings>
<MyDll.Properties.Settings>
<setting name="Hostname" serializeAs="String">
<value>127.0.0.1</value>
</setting>
<setting name="Port" serializeAs="String">
<value>1234</value>
</setting>
</MyDll.Properties.Settings>
</applicationSettings>
</configuration>
And also in this case, the LogPath is successfully passed on, but the settings for my.dll.config are not. The AssemblySettings instance is null:
AssemblySettings settings = new AssemblySettings();
// settings == null
What am I doing wrong?
Assembly.GetCallingAssembly().FullName in the constructor of AssemblySettings evaluates to "MyDll, Version=6.1.0.0, Culture=neutral, PublicKeyToken=null", but the returned instance is null.
I have a new (test) console application that I'm trying to access the settings.
When I attempt to access it this way, from what I've read on SO and other places, this should work:
var test1 = System.Configuration.ConfigurationManager.AppSettings["MySetting"];
but it doesn't, it returns null.
When I do it this way, it works fine:
var test2 = Properties.Settings.Default.MySetting;
Why doesn't the first one work? Everything I've read shows to use it the first way.
Am I using it incorrectly?
EDIT
In response to Mason.
I'm confused on your comment. The app.config is where the setting is being set from the properties of the application:
<?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="ConsoleApp1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<applicationSettings>
<ConsoleApp1.Properties.Settings>
<setting name="MySetting" serializeAs="String">
<value>testtesttest</value>
</setting>
</ConsoleApp1.Properties.Settings>
</applicationSettings>
</configuration>
System.Configuration.ConfigurationManager.AppSettings is for reading settings from the app.config or web.config files (for ASP.NET). It does not read from the settings files.
Because AppSettings refers to reading the settings in MyApp.config
I'm trying to read from my AppConfig but it's not working.
App.Config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Console.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<userSettings>
<Console.Properties.Settings>
<setting name="LogFiles" serializeAs="String">
<value>True</value>
</setting>
</Console.Properties.Settings>
</userSettings>
</configuration>
Program.cs:
namespace Console
{
class Console
{
public static readonly bool LogFiles = Properties.Settings. //Cant find symbol Default
static void Main(string[] args)
{
//Do stuff here
}
}
}
When using Properties.Settings i Can't find the Default symbol or LogFiles property. What am I missing?
Idiomatic way to achieve this is to use ConfigurationManager.AppSettings[key] instead. Config will look like:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="LogFiles" value="True" />
</appSettings>
</configuration>
And retrieval of application setting would be:
bool logFiles = Convert.ToBoolean(ConfigurationManager.AppSettings["LogFiles"]);
I'm running Visual Studio 12.0 targeting 4.5. I'm running VS Express. My App.config looks like this:
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ConfigMgrTest2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<applicationSettings>
<ConfigMgrTest2.Properties.Settings>
<setting name="exampleAppSetting" serializeAs="String">
<value>example app setting data</value>
</setting>
</ConfigMgrTest2.Properties.Settings>
</applicationSettings>
</configuration>
This allows me to use this syntax to access values:
string value = ConfigMgrTest2.Properties.Default.exampleAppSetting;
It seems from my research that I should have an "appSettings" section in my App.config that uses key-value pairs and looks like this:
<appSettings>
<add key="exampleAppSetting" value="example app setting data"/>
</appSettings>
This would allow me to access values like this:
string key = "exampleAppSetting";
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
string value = appSettings[key];
Using my App.config, any call to the ConfigurationManager.AppSettings property is obviously returning null.
The question is, Which version of App.config is "right"?
Both are right and current.
In your example,
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ConfigMgrTest2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
You have simply used System.Configuration.ApplicationSettingsGroup to define a new configuration group applicationSettings.
if you were to add this to your config file:
<appSettings>
<add key="Alfa" value="42"/>
</appSettings>
You could still retrieve it with:
var alfa = ConfigurationManager.AppSettings["Alfa"];
Update
Full App.config
<?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="ConfigMgrTest2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<applicationSettings>
<ConfigMgrTest2.Properties.Settings>
<setting name="exampleAppSetting" serializeAs="String">
<value>example app setting data</value>
</setting>
</ConfigMgrTest2.Properties.Settings>
</applicationSettings>
<appSettings>
<add key="Alfa" value="42"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Personally, I prefer custom configurations, since they allow me to provide for default values, as well as make some mandatory.
I am not sure about which version is proper, which may depend on your actual usage scenario but if you have the posted section in your app.config like below
<appSettings>
<add key="exampleAppSetting" value="example app setting data"/>
</appSettings>
Then you need to access it like below. You need to mention the KEY for which you are trying to get the value.
ConfigurationManager.AppSettings["exampleAppSetting"]
Assuming you have created a desktop application (WinForms or WPF) the App.config file is automatically copied to the output folder alongside with the executable and renamed to YourApplication.exe.config. It is inside this file that you could have the <appSettings> section:
<configuration>
<appSettings>
<add key="exampleAppSetting" value="example app setting data"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
and then you will be able to access this value like this:
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
string value = appSettings["exampleAppSetting"];
You might prefer using custom configuration sections when you have some complex config properties. In this case it might make more sense to move them in a separate configuration file and write a custom section.
Try to store and to read some user definde value to *.config file
Code for reading from file
public int GetVolumeFromConfigFile()
{
return Convert.ToInt32(ConfigurationManager.AppSettings["Volume"]);
}
Works perfect
Try to update existing key with this
public int SetVolumeFromConfigFile()
{
ConfigurationManager.AppSettings["Volume"] = "10";
}
Got error - file only for reading, change for something like this:
Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
config.AppSettings.Settings.Add(label.Text.ToString(), box.Value.ToString());
config.Save(ConfigurationSaveMode.Minimal);
Got no errors, but nothing changed in file.
My *.config file is :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="PlayDemo.SettingsPlayIt" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<userSettings>
<PlayDemo.SettingsPlayIt>
<setting name="Volume" serializeAs="String">
</setting>
</PlayDemo.SettingsPlayIt>
</userSettings>
Just try to understand where I'm wrong
Here it is
Configuration config = ConfigurationManager.OpenExeConfiguration(System.Windows.Forms.Application.ExecutablePath);
config.AppSettings.Settings["Volume"].Value = "10";
config.Save(ConfigurationSaveMode.Modified);
This won't update the App.config in your project in Visual Studio, but the "ExecutableName".config in the bin folder of your project.