I'm building a C# (WPF) application and I would like to use a simple configuration to define the file paths.
The purpose is for the user to be able to read and/or modify the configuration file easily and without having to learn any complicated syntax (or boilerplate), and to do it using a simple text editor.
I've been reading about the App.config file and from what I understand it is really complicated to modify by hand.
In the past in Windows and in Linux (even today) there were very simple Key=Value files that are exactly what I'm used to - however I see that C# doesn't have any builtin support for INI file reading/parsing.
Can an App.config file be modified easily by a user that isn't familiar with the syntax? If not is there any easy alternative?
For ease of editing, and to remove the complexity of the file as a whole, you can split the appSettings section out to a separate file, referenced from app.config...
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!- stuff in here -->
</configSections>
<appSettings configSource="myCustomisableSettings.config" />
</Configuration>
The separate file should look like this.
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="FirstPathKey" value="FirstPath" />
<add key="SecondPathKey" value="SecondPath" />
</appSettings>
For this situation, either using the app.config or web.config there is an appsetting's section that can contain key/value pairs for storing information such as file paths etc that are easily modifiable and readable:
<configuration>
<appSettings>
<add key="myFilePath" value="pathToFile" />
</appSettings>
....
</configuration>
you can add as many sections within the appSettings as you need
The App.config file is easily modified. The below is a standard App.config with a custom value.
<!-- Start Ignore here -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<!-- End ignore here, the below is what you want -->
<appSettings>
<add key="myCustomPath" value="C:\Path\To\Something"/> <!-- The user can edit this value -->
</appSettings>
</configuration>
As you can see all the user has to do is change the value under the appSettings node. It's that simple.
Then to access the value (in your code) all you have to do is call the ConfigurationManager:
var path = ConfigurationManager.AppSettings["myCustomPath"];
Related
I am unable to access CloudfigurationManager from within an method. The code was originally a klass library and I added a configuration file (App.config) where I am simply adding the values for a hard coded test for Azure SDK.
OpenSessionWithAzure()
private void OpenSessionWithAzure()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSetting["APP_SETTINGS"])// Visual Studio is unable to identify ConfigurationManager
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="StorageConnectionString" connectionString="DefaultEndpointsProtocol=https;AccountName=userName;AccountKey=Key"/>
<add name="SasPolicyName" connectionString="myPolicy"/>
</connectionStrings>
</configuration>
Is there a reason why I am unable to access the ConfigurationManager within my application or a known workaround?
The reason for this error was due to the fact that I did not:
Have a reference to System.Configuration.dll in my class library.
Did not have the using System.Configuration
After adding performing the steps above I am not able to access ConfigurationManager.AppSettings["APP_SETTINGS"]
You need to add reference to System.Configuration and then add key-value pair in appSettings section
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SasPolicyName" value="myPolicy" />
<add key="APP_SETTINGS" value="MySetting" />
</appSettings>
<connectionStrings>
<add name="StorageConnectionString" connectionString="DefaultEndpointsProtocol=https;AccountName=userName;AccountKey=Key"/>
</connectionStrings>
</configuration>
Then use like below,
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSetting["APP_SETTINGS"])
The method signature you use must be consistent with the setting in your App.config.
With the setting below,
<configuration>
<appSettings>
<add key="StorageConnectionString" value="XXXXXXXXX"/>
</appSettings>
</configuration>
use System.Configuration.ConfigurationManager.AppSettings["StorageConnectionString"].
And System.Configuration.ConfigurationManager.ConnectionStrings["StorageConnectionString"] for
<configuration>
<connectionStrings>
<add name ="StorageConnectionString" connectionString="XXXXXXXXXX"/>
</connectionStrings>
</configuration>
When you attempt to read from appSettings, it reads from the .config file of the executing application. So in the simplest implementation you'd just need to add those configuration settings to that application's .config file (app.config or web.config.) There are other ways to approach it if you absolutely need the library to have its own .config file, but adding it to the executing application's .config is what's done most commonly.
I have a program called parser.exe and it uses a config file called parser.config (a txt format; I read it with streamreader). For some reasons C# complains and doesn't like this.
Unhandled Exception:
System.Configuration.ConfigurationErrorsException: Configuration
system failed to initialize --->
System.Configuration.ConfigurationErrors
BUT if I created a file called parser.exe.config. with just followng content application runs fine:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
Why this is happening and how to suppress this problem without having parser.exe.config and changing the config name from parser.config to parser.exe.config?
it uses a config file called parser.config (a txt format; I read it with streamreader)
There's no need for this. .NET already has a perfectly good framework for application configuration files. Just add an app.config file to your project and Visual Studio will automatically create a parser.exe.config file when you build.
You can then use the ConfigurationSettings.AppSettings dictionary to read individual configuration items - or use more complex structured for more complex configurations.
To use an external configuration file for a config section, just use the configSource attribute in app.config:
<configuration>
<appSettings configSource="parser.config" />
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
parser.config:
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="Test" value="This is a test"/>
</appSettings>
why this is happening?
That's the way the framework was designed - it will look for a {executable name}.config file by default - you can add external config files as explained above but there's no way that I know of to have the framework look for a different file name by default.
You could load a new file into a separate configuration object:
ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
configMap.ExeConfigFilename = #"parser.config";
var config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);
But then you have to use that config instance to access config settings:
Console.WriteLine(config.AppSettings.Settings["test"].Value);
instead of
Console.WriteLine(ConfigurationManager.AppSettings["test"]);
But that seems like a long way to go to avoid the default config file name.
You can tell .NET to look for your settings in another file, like this:
<configuration>
<appSettings file="parser.config"></appSettings>
</configuration>
I have a class library application and am unable to configure a CONFIG file. My app.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="test" value="value test"/>
</appSettings>
</configuration>
and the call in my application:
var test = ConfigurationManager.AppSettings["test"];
But when I run, always passes a null value.
Class libraries do not use a .config file. Only applications (app.config) and web site s(web.config) read the "config" file.
The class library can use the Configuration Manager to read a value, but they must running inside of an app/web site.
In ASP.Net rename 'app.config' to 'web.config' and place it in the root folder of web site.
You have to put the appSettings tag in the web.config of your website in order to use ConfigurationManager.AppSettings["test"] if you do not want to do that then make the setting xml file and read it in your library code.
Add this code to the web.confg
<configuration>
<appSettings>
<add key="test" value="value test"/>
</appSettings>
</configuration>
And this is get value
var test = WebConfigurationManager.AppSettings["test"];
If you are passing string you may use
in webconfig
<appSettings>
<add key="test" value="value test"/>
</appSettings>
In cs.
String update = Convert.ToString(ConfigurationManager.AppSettings["test "]);
thank u all!
I used my config from my web application and solved the problem. It was something simple that I was complicating.
My project has 2 different config sections(one technical & one functional) and some connection Strings.
I would like to have in a same configSource file, the technical config section & the connection strings & in an other one the functional section. I know how to do this in 3 separate files but not in 2. It would be logical to have technical configuration like server hostnames & connection string in the same file.
My configuration files should look like this:
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="MyService.Functional" type="Logger.ConfigHandler, Logger"/>
<section name="MyService.Technical" type="Logger.ConfigHandler, Logger"/>
</configSections>
<MyService.Functional configSource="Config\MyService.Functional.Config"/>
<MyService.Technical configSource="Config\MyService.Technical.Config"/>
<connectionStrings configSource="Config\MyService.Technical.Config">
</connectionStrings>
</configuration>
MyService.Technical.Config
<MyService.Technical.Config>
<MyResourceServer value="tcp://MyServer:9000"/>
</MyService.Technical.Config>
<connectionStrings>
<add name="MyEntities" [...] />
</connectionStrings>
However if I mix the section MyService.Technical & the connectionStrings in the same file, the ConfigurationManager can't load any section anymore.
Do you have any tip to do this ? Is it absolutely mandatory to have 3 separate files for this case ?
From my experience, it seems to load the contents of the file as the inner XML of the referring element, which would mean you need to have different files for each section being externally referenced.
I'm working on a ASP.NET project and I need to add some settings in appSettings section of my web-app.
Now these settings are growing up, so I'd like to organize them in different files. I've created other web.config files in different directories of my application, adding something like this:
<?xml version="1.0"?>
<configuration>
<system.web>
</system.web>
<appSettings>
<add key="settingKey" value="settingValue" />
</appSettings>
</configuration>
But when I try to access them via ConfigurationManager.AppSettings["settingKey"], I get null.
So, is it possible to split settings in different files? Is there another way to logically organize app settings values?
I know this is too old and probably doesn't even apply to .NET Core but for those coming from Google and using non-.NET Core json config files. Here's what I normally do...
I use configSources to take all config settings out of the web.config. This allows you to a specific config section to a different file by providing a relative location for example here's how you'd declare a configSource in a configuration section (in the root web.config file)...
<configuration>
<log4net configSource="Config\debug\log4net.config" />
<appSettings configSource="config\debug\settings.config" />
<connectionStrings configSource="config\debug\connections.config" />
...
</configuration>
You can name those files whatever you want, just make sure that the path specified and files exist in the solution. Here's what the settings.config file looks like...
<?xml version="1.0"?>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="foo" value="bar" />
</appSettings>
Now, the relative path is relative to the project root...
In picture above you can see that I have provided two different paths for different deployment environments, that's because obviously my conection strings and settings are different in production.
Then you can use configuration transformations so that the application can use the correct config files whether it is in debug or release mode...
This is what the Web.Debug.config file looks like...
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<log4net configSource="Config\debug\log4net.config" xdt:Transform="Replace" />
<appSettings configSource="config\debug\settings.config" xdt:Transform="Replace" />
<connectionStrings configSource="config\debug\connections.config" xdt:Transform="Replace" />
</configuration>
The release one is pretty much the same...replace the paths provided to the configSource attributes.And that's pretty much it.
There are other web.config elements that support configSource settings such as many of the system.serviceModel children element.
You will only be able to see the web.config settings within a directory if the currently executing path is within that directory.
So for example:
/MyDirectory/web.config
is only visible if you are loading a page like:
/Mydirectory/MyTestPage.aspx
You would not see the web.config settings here for example:
/OtherDirectory/MyTestPage.aspx
This post may help:
Creating a custom .config file in asp.net