multiple config file in c# - c#

I have a solution containing 1 console application and 2 libraries.
In the libraries I have two different app.configs for an example my data.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="OutputFileFolder" value="c:\\log" />
<add key="OutputIndexFile" value="c:\\log\index.xml" />
</appSettings>
</configuration>
And in this library class I have in the constructor
_indexPath = ConfigurationManager.AppSettings["OutputIndexFile"];
But how should I load the Data.config file from my main console application (this should be the main config file)?

Config files in your dll projects are not relevant at runtime. The config file (if any) in your console application project is the one that will get used.
If you want to use a configuration file in two separate projects, you can add it as a link to your second project, or you could use a post-build event to copy it over. However both of these seem a little hacky.

Libraries don't really have associated configuration files as such - they operate under an executable (a console application, in your case).
You should put all the configuration in the app.config file of the application for the code in the libraries to have access to it.

You can load multiple config files by have multiple Configuration instances from multiple calls to ConfigurationManager.OpenMappedExeConfiguration (add your config file to the file map, the global file will be added automatically and specify a ConfigurationUserLevel.None.
Something like:
var fileMap = new ExeConfigurationFileMap {
ExeConfigFilename = Path of dll's config file
};
var cfg = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
var result = cfg.AppSettings["OutputIndexFile"];

Related

App.config file not getting read from non-startup project

In my solution I have two projects, one which is set to the startup project, the other not. I have added an App.config file to the start-up project.
The App.config file works in the project which is the startup project, but I cannot read the App.config from the other project, the data is coming back as null.
If I want my non start-up project to access the App.config file in the start-up project, what settings do I need to change?
I am using the following code to access the file. String testrail is coming back as null when running from the non start-up project.
public string testrail;
testrail = ConfigurationManager.AppSettings["testrail"];
My App.config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="testrail" value="True"/>
</appSettings>
</configuration>

.net standard ConfigurationManager opens wrong app.config

I'm trying to run a test method from a .net core unit test project over a .net standard project and when loading config file which is in the test project (as this is the current executing assembly). I'm getting a wrong config file with the current file path "C:\Users\xxx\.nuget\packages\microsoft.testplatform.testhost\15.3.0-preview-20170628-02\lib\netstandard1.5\testhost.dll.config"
var conf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
You have the option to point to another config file. The credit for the source goes to the Ron Hagerman for his answer with only slight modifications. The following xunit test may help with understanding on how to set the location. It is frustrating that .net core unit tests looks for the connection string in the testhost.dll.config file in the following directory
C:\Users\[UserName]\.nuget\packages\microsoft.testplatform.testhost\[version]\lib\netstandard1.5\testhost.dll.config
[Fact]
public void AccessAppSettings_ConnectionString()
{
//obtain the current directory for the executable
Uri UriAssemblyFolder = new Uri(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly()
.GetName().CodeBase));
string appPath = UriAssemblyFolder.LocalPath;
//Change the "DataProvider.Tests.dll" to whatever your
//library or executable name.
//Note: Configuration manager will add the .config extension
Configuration config = ConfigurationManager
.OpenExeConfiguration(appPath + #"\" + "DataProvider.Tests.dll");
ConnectionStringsSection section =
config.GetSection("connectionStrings") as ConnectionStringsSection;
string expectedString = $"Data Source=mysqliteDBName.sqlite3";
//Change "mySqliteConnectionString" to your connection string name
var sut_connectionString =
section.ConnectionStrings ["mySqliteConnectionString"].ConnectionString;
Assert.NotNull(sut_connectionString);
Assert.Contains(expectedString, sut_connectionString);
Sample Config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="mySqliteConnectionString" connectionString="Data Source=mysqliteDBName.sqlite3" />
<add name="otherConnectionString" connectionString="Data Source=othersqliteDBName.sqlite3" />
</connectionStrings>
</configuration>
I don't think you are getting the wrong one. You are getting the Test project's config file which is the correct one since you are running the Test project.
Every project has it's own config file or none. It cannot just go and load another project's config file.
Bottom line is: just copy whatever specific config you want from your .net standard project's config file to your unit test's config file.

Getting Connectionstring values from Other config file in subfolders and add the connectionstring to the root app.config file

I am using a windows application in which I have config files (dev.config, prod.config, uat.config) located in multiple folders such as dev, prod, uat. I want to get the particular config file values such as connectionstrings based on the certain condition from a particular folder and I want to add the corresponding connectionstrings in the root app.config file. Then I need to fetch data based on the added connection string. Can anyone help me on this?
What you can do pretty easily is to externalize your connection strings (we tend to put them into App_Data\config, since that folder is protected by IIS and nothing from that folder will be returned when trying to browse it)
So in your main web.config, you would have something like this:
<connectionStrings configSource="App_Data\config\dev.config" />
and then you go to testing, you just change that to
<connectionStrings configSource="App_Data\config\uat.config" />
and in your individual config files, you just have that one section:
dev.config:
<connectionStrings>
<add name="SomeName"
connectionString="server=.;database=test;integrated Security=SSPI;"
providerName="System.Data.SqlClient" />
......
</connectionStrings>
You could load a custom config file based on a condition using ExeConfigurationFileMap and ConfigurationManager.OpenMappedExeConfiguration().
ExeConfigurationFileMap configFileMap = ExeConfigurationFileMap("path/to/custom.config");
System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None)
When you have the config object, you can then pick the given section you need, in your case the connectionstrings.
ConnectionStringsSection connectionStrings = config.ConnectionStrings;
You could then load whichever config file you want based on the conditions you want, and pick out the parts you'd like.
More info about the ConnectionStringsSection with a short example (MSDN).

AppSettings in App or Web Config Using a Linked File

I'm trying to reference some common config settings between a Windows Service and an ASP.NET MVC website. I am doing this by using the file attribute on appSettings in either the App.config or Web.config (respectively). The file (named common.config) that is being referenced is a linked file in a separate project in the same solution. That common.config is set to Content with Copy Always in both projects.
This stack answer to a similiar question seems to suggest at least for configSource this solution would work. I don't want configSource though as I only want a handful of the properties to be common amongst the two projects. Update: I just tried this, and the configSource also doesn't work. It can't find the config file. This leads me to believe the common.config is not treated as content with copy always.
Example App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="common.config">
<add key="NotCommonKey" value="1"/>
</appSettings>
</configuration>
Example Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings file="common.config">
<add key="NotCommonKey2" value="2" />
</appSettings>
</configuration>
Example common.config (Content -> Copy Always)
<appSettings>
<add key="CommonKey" value="1" />
</appSettings>
I am using ConfigurationManager / WebConfigurationManager reading from the AppSettings property.
Any ideas why when the common.config is a linked file, it's AppSettings values are not used and when it is not linked it works as normal?
Thanks!
In the Web.Config you must add "bin/" (se example below).
By default the web.config is NOT copied into the bin folder but the file common.config is, therefore you must add the path from web.config. In a non-web project the default behavior is that the App.config is copied to the bin folder with name MyProgram.exe.config and is in the same directory as common.config.
<appSettings file="bin/common.config">
The idea of using "bin/..." is good but leads to an error saying that "/" is an invalid character in the resulting virtual path.
The proper solution is tu use "bin...".
Cheers
I use this to access another .exe's config file, not sure whether it will work with a MVC project, but this might get you closer:
string proj2Exe = #"C:\projects\proj2\bin\Debug\proj2.exe";
Configuration proj2Config = ConfigurationManager.OpenExeConfiguration(proj2Exe);
string mysetting = proj2Config .AppSettings.Settings["ThatSetting"].Value;

Hiding private details from open source projects

I have a .net github project that is basically a wrapper around a web API. In the test project, I am calling to the API using an API key. I need to keep this key private, how do I accomplish this in a visual studio project?
In some other projects, like python, I can have git ignore the file (config.py) and use something like config.example.py. But in visual studio's case, the project will not compile because of the missing file Config.cs. What is the proper way to solve this? I'm thinking of using this same method of ignoring the file and have them execute a build script that should rename Config.example.cs to Config.cs?
This is the perfect for .config files. Depending on whether its a web or console application, you will have a web.config or app.config file in your project.
You can use the appSettings section to store your API key.
To make things even easier, you can actually have this section read from another file, ie: specialappsettings.config and then just ignore that single file from your repository.
Modify your web.config (or app.config):
<configuration>
<appSettings file="specialappsettings.config">
</appSettings>
<system.web>
<!-- standard web settings go here -->
</system.web>
</configuration>
Create a new specialappsettings.config file:
<appSettings>
<add key="APIKey" value="YourApiKeyValue" />
<add key="AnotherKey" value="AnotherValue" />
</appSettings>
This can be accessed in your code via:
var apiKey = ConfigurationManager.AppSettings["APIKey"];
Notes:
You can keep your settings within the original web.config file as
well but this lets you ignore just the specific settings file from
your git repository without affecting the rest of the project's
necessary configuration details.
The same "key" can be saved in
either file however the external file will override the original
web.config file value.
You are probably looking for the App.config file for a project. It will be copied to <application>.exe.config when you compile it. Users can edit that config file as needed.
In that config file, you can add your API keys:
<configuration>
<appSettings>
<add key="APIKey" value="12345"/>
</appSettings>
</configuration>
Then you can access it from your code using ConfigurationManager.AppSettings:
string apiKey = ConfigurationManager.AppSettings["APIKey"];
One option is to use .config files instead of having secret keys hardcoded in sources.
More info Using Settings in C# and step-by-step guide
<configuration>
<appSettings>
<add key="SecretKey" value="0" />
</appSettings>
</configuration>
var secretKey = ConfigurationManager.AppSettings.Get("SecretKey");
Perhaps you can store the key outside of the Config.cs file and load it at run time.
Bonus, other people using your code won't have to recompile the project to change to their API key.

Categories