Saving appSettings to an external file - c#

I need to have appSettings in a separate file and in a parent directory and save it at runtime:
Bin/app.config:
<appSettings file="../Configuration/appSettings.config">
<add key="commonSetting" value="123"/>
</appSettings>
Configuration/appSettings.config:
<appSettings>
<add key="externalSetting" value="ABC"/>
</appSettings>
When I try to modify and save external settings, they are saved in Bin\app.config instead of Configuration/appSettings.config:
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationManager.AppSettings["externalSetting"] = "DEF";
config.Save();
I can't use configSource attribute because external file has to be in a subdirectory of Bin.
(Similar problem raised in AppSettings on a different .config file not being updated but not the same constaints)
Any idea of how to fix / work around it?
EDIT:
I also tried with this setter, same unexpected result:
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["externalSetting"].Value = "DEF";
config.Save();

Related

C# - Unable to write to app.config after deployment

I am developing a WPF application which runs well in visual studio v.2022 very well. My problem is when I deploy the application to another computer for testing it does not seem to be updating app.config data. When I change the ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) to NONE it works well in both debug and release mode in Visual Studio but throws an error when deployed to another computer. The error I am getting is "System configuration.configuration error exception - An error ocurred while loading the the configuration file myApp.dll.config. Access denied "
I gather that the user has no write privileges on the Program Files folder where the app.config is stored. However, when I change the user level to either Roaming or Roaming and local, then nothing happens as the configuration file is not located and if at all the changes are made then they are not persisting. Here is my app.config file
<configuration>
<appSettings>
<add key="Server" value=""/>
<add key="Port" value=""/>
<add key="Database" value=""/>
<add key="User" value=""/>
<add key="Pwd" value=""/>
<add key="Code" value=""/>
<add key="Access" value=""/>
<add key="Status" value=""/>
<add key="EndDate" value=""/>
</appSettings>
</configuration>
Here is my method for updating the the app.config
public static void UpdateSetting(string key, string value)
{
Configuration roaming = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = roaming.FilePath;
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var appSettings = configuration.AppSettings;
foreach (var keys in appSettings.Settings.AllKeys.Where(x => x.StartsWith(key)))
{
appSettings.Settings[keys].Value = value;
}
configuration.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
and here is an example of how the method is called Settings.UpdateSetting("Code", _Code);
Any help will be much appreciated
Following #Joe's comment it occurred to me that it was not possible to write to config application data at runtime. I opted to create a new section in the config file in the Properties.Settings folder in my solution and assigned the scope to User and not application since the user is able to update the data at runtime. Double click on the settings.Settings file to open in designer view and literally entered the settings names to be stored.
The stored settings can be saved and retrieved using the methods below.Properties.Settings.Default.yourSetting. to get the settings.
And to store/save the settings
Properties.Settings.Default.yourSetting= val;`
Properties.Settings.Default.Save();`
That solved my problem.

Additional config files

I have loaded the default App.config file in my solution and I'm able to access stored variables from it.
XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="foo" value="bar"/>
</appSettings>
</configuration>
C#
Configuration configManager = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
KeyValueConfigurationCollection config = configManager.AppSettings.Settings;
string foo = config["foo"].Value;
Now I have created another configuration file to store variables for another part of my solution, but I can't figure out how to load it the same way with ConfigurationManager.
Configuration config2 = ConfigurationManager.OpenExeConfiguration("path/to/config.config");
Perhaps you are looking for this:
ExeConfigurationFileMap exeConfigurationFileMap = new ExeConfigurationFileMap();
exeConfigurationFileMap.ExeConfigFilename = "your file path here";
Configuration customConfig = ConfigurationManager.OpenMappedExeConfiguration(exeConfigurationFileMap, ConfigurationUserLevel.None);

Read separate web.config file outside the application folder

I need to read web.config file, outside the application's folder (located in any other directory).
I tried this code:
string filePath = #"C:\Users\Idrees\Downloads\New folder\Web.config";
Configuration c1 = ConfigurationManager.OpenExeConfiguration(filePath);
var value1 = c1.AppSettings.Settings["Key1"].Value;
But it is giving me the error:
Object reference not set to an instance of an object.
Because here, c1.AppSettings is an object, but c1.AppSettings.Settings contains not items (hence 0 Count). It is not really loading the AppSettings keys. When trying to read any Key from Settings collection, it gives this error.
Is there any way how to load AppSettings keys from a web.config file outside the application folder.
If I put same file within application folder, then it reads the keys successfully.
This is my sample config file's content:
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<!--here goes my connection strings-->
</connectionStrings>
<appSettings>
<add key="Key1" value="Value1" />
<add key="Key2" value="Value2" />
<add key="Key3" value="Value3" />
</appSettings>
</configuration>
I have a web application already running on my server. And I need to develop a small utility which has to do some job in database, and I don't want to write db credentials or connection string(and some other additional app-settings) in each application, I want it to read same thing from web.config.
You can using ConfigurationManager to read arbitrary configuration files by opening a mapped exe configuration as follows:
var filePath = #"C:\Users\Idrees\Downloads\New folder\Web.config";
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = filePath };
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var value = configuration.AppSettings.Settings["Key1"].Value;
As I understand from your comment you want some kind of shared configuration accross multiple app on the same computer. You may consider using external file like this :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<connectionStrings configSource="config\connString01.config"/>
<appSettings file="config\config01.config">
<add key="Var3" value="Var3 value from main config file"/>
</appSettings>
in above .config example connectionStrings is sourced from an other file. Below an example what can be such an external config file:
<connectionStrings>
<add name="SQLConnectionString01" connectionString="Data Source=sourcename01;Initial Catalog=cat01;Persist Security Info=True;Integrated Security=true;"/>
</connectionStrings>
Read documentation: ConfigurationManager.OpenExeConfiguration on MSDN
public static Configuration OpenExeConfiguration(
string exePath
)
This is EXE path

C# Opening a configuration file from an arbitrary location

At:
Using ConfigurationManager to load config from an arbitrary location
I found what seems like a solution. A project I'm working on uses an appSettings.config file location on the network. BUT when I tried to use the referenced code:
System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap("Z:\Settings\appSettings.config"); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
So far so good. The appSettings.config file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="Environment" value="Development" />
</appSettings>
</configuration>
BUT then I get to this following line:
var settings = configuration.AppSettings.Settings;
or anything using it, like Settings.Count, I get an Invalid Cast Exception. Basically, how would I get the value for "Environment" from this?
I found this works:
System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = #"Z:\appSettings.config"; //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); // OpenMappedMachineConfiguration(fileMap);
return configuration.AppSettings.Settings["Environment"].Value;
This works without error.

.net and .config files

I have the following stored in a stores.config file inside my asp.net website's root folder.
<configuration>
<appSettings>
<add key="ClientId" value="127605460617602"/>
<add key ="RedirectUrl" value="http://localhost:49548/Redirect.aspx"/>
</appSettings>
</configuration>
How can I use string Clientid = ConfigurationManager.AppSettings["ClientId"].ToString(); to call it up from that file? Calling it as it of course does not work as it is looking for it in web.config.
I do not want to put the appSettings in the web.config file. Is that allowed?
You can reference your stores.config file from web.config
<configuration>
<appSettings file="stores.config">
</appSettings>
<configuration>
Your stores.config file should have the following structure:
<appSettings>
<add key="ClientId" value="127605460617602"/>
<add key ="RedirectUrl" value="http://localhost:49548/Redirect.aspx"/>
</appSettings>
Alternatively you can also use:
ConfigurationManager.OpenMappedExeConfiguration Method (ExeConfigurationFileMap, ConfigurationUserLevel)
For example:
// Map the new configuration file.
var configFileMap = new ExeConfigurationFileMap();
configFileMap.ExeConfigFilename = "stores.config";
// Get the mapped configuration file
var config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
var clientid = config.AppSettings["ClientId"];

Categories

Resources