.net standard ConfigurationManager opens wrong app.config - c#

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.

Related

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).

Getting ConnectionString of a BizTalk config file from a C# Application

I have a BizTalk config file that I want to use in my C# application. I'd like to get the connection string from the BizTalk config. Is there a way to do this? Simply put, I want to read a connection string from an external config file.
What I'm currently using in my C# app config is:
<configuration>
<appSettings>
<add key="foo" value="blah;"/>
<add key="foo" value="blah;"/>
</appSettings>
</configuration>
I get the keys by using this code:
connectionString = ConfigurationManager.AppSettings[configKey];
Thanks.
From an external .config file, as in not the current .exe's config file, no.
System.Configuration will always refer to the local .config.
To access another .exe's .config file, you have to treat it as just an Xml file with System.Xml.

Merger app.config from custom location

I have a scenario where I need to read an environment variable on start, then depending on the value of the ENV variable I need to merge a config file with the App.config file.
E.g.
MyApp.exe
MyApp.exe.config
Stage\MyApp.exe.config
Live\MyApp.exe.config
On start
-if the Environment variable = Stage, then Merge the config file in the Stage folder
-if the Environment variable = Live, then Merge the config file in the Live folder
If I had the following in the default MyApp.exe.config
<appSettings>
<add key="SomeKey" value="SomeValue">
</appSettings>
and then had the following in the Stage\MyApp.exe.config
<appSettings>
<add key="SomeKey" value="Some NEW Value">
</appSettings>
I'd expect my application to read the value for SomeKey as "Some NEW Value".
I can't seem to find a clean way to implement this exact approach.
Thanks
Warrick
You might want to use Build Events in Visual Studio.
http://msdn.microsoft.com/en-us/library/42x5kfw4(v=vs.90).aspx
You can use the variable to copy the overwrite the app.config in the pre-build event:
$(ConfigurationName)
If the config name is DEV, then copy the app.config.DEV over the app.config
If the config name is PROD, then copy the app.config.PROD over the app.config

multiple config file in 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"];

App.config AppSettings return null

I have a project that is a WCF client using netTCP endpoints. The project compiles into a DLL that is referenced by another project. I use AppSettings to switch between local and remote ip endpoints like so:
public EmbeddedClient()
{
//Grab ip to use: remote or local (used for simulator)
String location = ConfigurationSettings.AppSettings["ipAddress"];
String ip = ConfigurationSettings.AppSettings[location];
//Default to localhost if no appsetting was found
if (ip == null)
ip = "localhost";
String address = String.Format("net.tcp://{0}:9292/EmbeddedService", ip);
//Setup the channel to the service...
channelFactory = new ChannelFactory<IEmbeddedService>(binding, new EndpointAddress(address));
}
My App.Config is where I have my AppSettings and WCF endpoints:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ipAddress" value="local"/>
<!-- Replace above value to "local" (Simulator) or "remote" (Harware)-->
<add key="local" value="localhost"/>
<add key="remote" value="192.168.100.42"/>
</appSettings>
<system.serviceModel>
<!--WCF Endpoints go here--->
</system.serviceModel>
</configuration>
When I compile the project the appsetting always returns a null. I also noticed that app.config is renamed to something like Embedded_DCC_Client.dll.config after compiling. Why is it not able to find my appsettings? Why is it returning null? Thanks.
It sounds like you're trying to use a config file with the DLL - that won't work. You need to set your app settings and WCF-specific settings in the app file of the application that references the WCF DLL. Th DLL will use the config file of the calling application.
In other words:
MyWCF.dll - this is your WCF DLL.
MyApplication.exe - this is an application that references WCF.DLL.
You would put your app settings and system.serviceModel settings in the app.config file of MyApplication.exe. MyWCF.DLL should then read the values from that config.
The app settings file is loaded from the context of the application that is started, so it needs to either be in that project or referenced from the startup project.
The folder which is used to Install utility should contain the Exe file, supporting dll and exe.config file

Categories