Overriding App.Config settings - c#

We have an app.config file that lists specific endpoint addresses and also some additional service settings. We would like to change these settings using an external config file set by the environment that it is placed in. What we would like it to do is dynamically read the external config file for that environment without hard coding values.
I know there is a way to specify an external file in the section specific to that section. Is there a way to dynamically set this location?

I ended up just setting it to an external config file by modifying the setting with:
System.Configuration.AppSettingsSection appsettings = config.AppSettings;
appsettings.File = Environment.CurrentDirectory + "\\configs\\" + configFile;
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appsettings");
That will allow you to dynamically set it to whatever config file you want it to be.

Your first question - yes, you can "override" any configuration section (such as <client>, <bindings> etc. not section group such as <system.serviceModel>) with an external file:
<client configSource="yourCustomClient.config" />
Visual Studio will highlight this with errors - but it works! - it's just a deficiency of Visual Studio's editor here.
Your second question: no, I don't believe there's any way to make this truly dynamic - the best I can think of is having some sort of an XML transformation of your config file at build and/or install time.

I do think this link will help you do dynamically load any App.Config file and use WCF services.
Yours,
Alois Kraus

My recommendation is to do any wcf configuration within the xap and passing in the environment information as a parameter. All WCF configuration calls can be done through code without the use of the settings in the web.config

Related

Is Web.Config the same as app.exe.config? [duplicate]

when building a desktop app in wpf can you read documentation of problems and safely subsititute 'app.config' when people's answer's refer to 'web.config'?
if so are there any glaring GOTCHAS you have to look out for?
tnx
Read the Documentation:
Web.config and App.config
The choice of the
configuration file name is determined by the hosting environment you
choose for the service. If you are using IIS to host your service, use
a Web.config file. If you are using any other hosting environment, use
an App.config file.
In Visual Studio, the file named App.config is used to create the
final configuration file. The final name actually used for the
configuration depends on the assembly name. For example, an assembly
named "Cohowinery.exe" has a final configuration file name of
"Cohowinery.exe.config". However, you only need to modify the
App.config file. Changes made to that file are automatically made to
the final application configuration file at compile time.
In using an App.config, file the configuration system merges the
App.config file with content of the Machine.config file when the
application starts and the configuration is applied. This mechanism
allows machine-wide settings to be defined in the Machine.config file.
The App.config file can be used to override the settings of the
Machine.config file; you can also lock in the settings in
Machine.config file so that they get used. In the Web.config case, the
configuration system merges the Web.config files in all directories
leading up to the application directory into the configuration that
gets applied.
Web.Config is used for asp.net web projects / web services.
App.Config is used for Windows Forms, Windows Services, Console Apps and WPF applications
Your question isn't providing all the information as to where the gotcha's may lie for you.
Can you give us more info on what you are trying to do in terms of these config files?
Here's a link...
Problems with Web.config and App.config

Common app.config for multiple applications

I have several C# console applications, which need to have the same set of settings. I want to avoid duplicity and avoid separate app.config for each application.
Is there any way to read a common app.config file (say common.config) for applications (app1.exe, app2.exe).
Create one file called app.config. Put it in some place outside of your projects' directories, like up in the solution directory. Add it to your projects as a linked item with a relative path to the file. Set the right build action for this item (application configuration) in each project.
Now when each project builds, the file will be copied to the project's output dir with the right name.
You can load an external app.config using the code below:
config = ConfigurationManager.OpenExeConfiguration(Path.Combine("C:\test\root", "Master.exe"));
string logpath = config.AppSettings.Settings["Log.Path"].Value;
And save settings as so:
config = ConfigurationManager.OpenExeConfiguration(Path.Combine("C:\test\root", "Master.exe"));
config.AppSettings.Settings["Log.Path"].Value = "C:\newpath";
config.Save();
You might have to have a master config within one of the applications and point the rest to this. Typically this method is considered bad practice though. There might be issues with different applications locking the file.
#Ran's answer is an option, but each application will still have its own config file after you build. At compile time they will be the same, but at deploy time they are copies.
You can also open one application's config file from another application using:
ConfigurationManager.OpenExeConfiguration(string)
You can have an external config file that all applications reference using:
ConfigurationManager.OpenMappedExeConfiguration
And there's the option to using the Machine config file using:
ConfigurationManager.OpenMachineConfiguration()

How to read values from App.config in .Net 4.0 using configurationManager?

I am creating a windows service in .Net 4.0 and testing some functions of said service with a windows forms client by referencing the service project.
The service project has an App.config file and that file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<clear />
<add name="myLocalMySQLDBUsername" connectionString="username"/>
</connectionStrings>
</configuration>
When a function belonging to the service calls:
ConfigurationManager.ConnectionStrings("myLocalMySQLDBUsername").ConnectionString
a null reference error is thrown because my connection string is not loaded. The only connectionStrings that are loaded are from the machine.config file located in c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Config\machine.config
If I create an application scope setting for the service, I can get that setting by using the My.Settings.setting -> so it's not like the App.config file is not being read.
My question is: why are my connectionStrings not being loaded from the App.config file?
Thank you for your help.
UPDATE:
Also, at this point, even a work around would be appreciated; the only reason for using app.config is to be able to encrypt the contents using the DpapiProtectedConfigurationProvider (the contents will have some username/password values for service and database connections).
I tried creating an AppSettings section manually in the app.config but those settings were also not read by the configurationManager (count = 0).
UPDATE 2:
Per a suggestion, I tried to manually open the app.config file like so:
Dim exePath As String = System.IO.Path.Combine(Environment.CurrentDirectory, "ServiceName.exe")
Dim myConfig As Configuration = ConfigurationManager.OpenExeConfiguration(exePath)
So here is the weird part, when I look inside, path is correct (points to my app.config) but the connectionStrings are still being loaded from the machine.config file (my connectionStrings are not loaded)!! ARGH
UPDATE 3:
Okay, so, I figured it out. When referencing a project(parent) from another project(child), the child's app.config is used even if the parent's classes are being used. Thus, I can get the connectionStrings to show up if I copy them over to the child's app.config. When trying to open it manually, my currentDirectory was of the child, not the parent (strange how it did not throw an exception - it wouldn't have been able to find the config file ... it just silently used the machine.config ... oh well).
Thanks all for the help!
The first thing you'll want to do is make sure that the service account has access to the file (if not running as SYSTEM). It sounds like it should be ok though since you mention My.Settings.Setting works.
The other thing to look out for is to make sure that the app.config has the name of the service executable in it - so if the service exe is MyService.exe the app.config must be named MyService.exe.config.
The last thing to make note of: libraries will read from the executable's app.config that loads the library, not the app.config that is with the library. So if you have a project for the service executable MyService and a project for the library MyServiceLibrary the code in the library will read the app.config from MyService not MyServiceLibrary.
I saw some people say this problem might be fixed by manually re-adding a reference to System.Configuration.dll
SIDE NOTE: If that really is you whole app.config file and not just a snippet then that is your problem... you're app.config file should be MUCH more complicated or .NET will not be able to load it.
WORK AROUND: Use the configuration manager to open this config file (there is an API for that.) You can't get it to load auto-magically just tell the config manager to open it.
I still think the problem is your config file is invalid -- could you please post the FULL file?
Make sure the config file is deployed to the same folder as the executable file, and that it's called your.assembly.exe.config.
I had a similar problem, but in my case it was because I had changed the project's namespace. This is also used as the application settings section element name in the config file, so the code was not finding the new section name. Fiddling with one of the custom setting's values in the project properties and rebuilding caused the new section to written into the app.config alongside the old ones which was what indicated the issue to me.

What's a good solution to have a configuration settings specific to a machine?

HI,
I want to have set configuration settings for a unit test project that is only relative for one machine ( i.e build machine). So for e.g. is the unit test project is being compiled on a developer machine then use settings A from App.config, if it's compiled on a build machine then use settings B from App.config. Is there a best practice for this sort of things?
In the appSettings tag, you can add an attribute like:
<appSettings file="moreSettings.config">
Inside the 'moreSettings.config' file, you create an tag that contains key-value pairs for any of the key-value pairs that you want to override from the main App.config file.
you can use conditional compilation symbols (just same as macro in C/C++) also...
Well, i guess you could check the hostname (this should be possible in almost any language or build environment) and depending on that decide what settings to use.
However i would not advise you to "automagicly" decide to do a developer/debug build. But rather i would suggest you provide a "switch" either on comandline or in a config file. Which you than explicitly enable in your setup on the development/test machine.

Programatically adding sections to the configuration read from app.config

I am working on a component/assembly that is to be distributed to other developers and included in their systems.
In order to minimize the work they have to do, all configuration is done in a seperate file (my.config).
My current problem is that a library I am using requires configuration to be added to the app.config file of the application. I have no way of modifying this, so that it reads my custom config file.
Is there any way to add a section/setting to the current config, so that it behaves as if it was read from the app.config?
I can add to the app.config, so it must work at runtime only.
Thanks, Jonas
I don't think you can update the configuration without changing the underlying file. It's a read-only thing.

Categories