How to use application config file in C#? - c#

I am trying to use a config file in my C# console application. I created the file within the project by going New --> Application Configuration File, and naming it myProjectName.config. My config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SSDirectory" value="D:\Documents and Settings\****\MyDocuments\****" />
</appSettings>
</configuration>
The code to access it looks like this:
private FileValidateUtil()
{
sSDirFilePath = ConfigurationSettings.AppSettings["SSDirectory"];
if (sSDirFilePath == null)
Console.WriteLine("config file not reading in.");
}
Can anyone lend a hint as to why this is not working? (I am getting the error message.)
Thanks!!
badPanda

You can't change the name from app.config and expect ConfigurationManager to find it without providing it more information. Change the name of myProjectName.config back to app.config, rebuild, and you will see a file in the bin folder called myProjectName.exe.config. Then your call to ConfigurationManager.AppSettings should work correctly.

check the documentation
http://msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx

First off, use ConfigurationManager instead of ConfigurationSettings.
Second, instead of saying "doesn't work", which provides no useful information, tell us what you're seeing. Does it compile? Does it throw an exception at runtime? Does your PC start to smoke and smell like melting plastic?
Try this:
public string GetSSDirectory()
{
string sSDirFilePath = string.Empty;
if (!ConfigurationManager.AppSettings.AllKeys.Contains("SSDirectory"))
{
Console.WriteLine("AppSettings does not contain key \"SSDirectory\"");
}
else
{
sSDirFilePath = ConfigurationManager.AppSettings["SSDirectory"];
Console.WriteLine("AppSettings.SSDirectory = \"" + sSDirFilePath + "\"");
}
return sSDirFilePath;
}

Related

How to read a user created Configuration file in C# [not web.config]

This is my current solution structure
Solution ABC
ProjectA
ProjectB
ProjectWeb
AppData --> CMS --> Configurations -->oneABC.config
Areas -->Produts --> Web --> abc.cs [where I need to access that config]
Web.config
ProjectC
PFB oneABC.config file
<?xml version="1.0" encoding="utf-8"?>
<oneABC xmlns:config="urn:configuration" xmlns:type="urn:configuration:type" config:version="12.2.7239.0">
<countrycredentials>
<add name="abbpoland" password="d0da0956b411" view="True" code="PL" />
<add name="abbitaly" password="25430aa9fa22" view="True" code="IT" />
</countrycredentials>
</oneAbbExternalDistributorInventoryConfig>
its not part of web.config and the value inside oneABC.config are not static as we can have multiple add or single add as well.
Right now i need to fetch the details from this config file and use it to do some operations, I have done some digging to fetch these details but found none related to my problem.
PFB the function that i have written inside abc.cs to fetch the details:
//in culture im getting lang like 'en' ,'pl' or 'it' as per the url
public static bool GetConfigurationValue(string culture)
{
string lang = culture;// im storing that language
ExeConfigurationFileMap customConfigFileMap = new ExeConfigurationFileMap();
// in below i need to mention the path of config file right now its not working as its checking this file from C:\Program Files (x86)\IIS Express\OneABC.Config
customConfigFileMap.ExeConfigFilename = "OneABC.Config";
Configuration customConfig = ConfigurationManager.OpenMappedExeConfiguration(customConfigFileMap, ConfigurationUserLevel.None);
AppSettingsSection appSettings = (customConfig.GetSection("countrycredentials") as AppSettingsSection);
// below i need to save those tag value in such a way that if lang = PL then ill use view as true and return true
//and if ill get it in lang then ill use view as false and return false
}
is there any universal way to set the file path of this file since currently im checking this in local and the ill need to deploy it to some server so file path will change.

C# ASP MVC pulling data from the web config file is not working

I'm trying to pull data from the web config file as outlined by this msdn resource.
Here is my code:
System.Configuration.Configuration activeCampaignApiSetting1 =
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(null);
if (activeCampaignApiSetting1.AppSettings.Settings.Count > 0) {
System.Configuration.KeyValueConfigurationElement activeCampaignApiKeySetting =
activeCampaignApiSetting1.AppSettings.Settings["ActiveCampaignApiKey"];
if (activeCampaignApiKeySetting != null) {
activeCampaignApiKey = activeCampaignApiKeySetting.Value;
}
System.Configuration.KeyValueConfigurationElement activeCamapignApiUrlSetting =
activeCampaignApiSetting1.AppSettings.Settings["ActiveCampaignApiUrl"];
if (activeCamapignApiUrlSetting != null) {
activeCampaignApiUrl = activeCamapignApiUrlSetting.Value;
}
}
When I try to instantiate this class:
var acs = new Acs(activeCampaignApiKey, activeCampaignApiUrl);
it throws an exception telling me that the values are blank.
The values in the web config file are there:
<add key="ActiveCampaignApiKey" value="apikey_removed" />
<add key="ActiveCampaignApiUrl" value="apiurl_removed" />
Anyone know where I may be going wrong?
Cheers
If they are appSetting inside web.config, you can access them via ConfigurationManager.AppSettings.
<?xml version="1.0"?>
<configuration>
<configSections>
<appSettings>
<add key="ActiveCampaignApiKey" value="apikey_removed" />
<add key="ActiveCampaignApiUrl" value="apiurl_removed" />
</appSettings>
</configSections>
</configuration>
string activeCampaignApiKeySetting
= ConfigurationManager.AppSettings["ActiveCampaignApiKey"];
string activeCamapignApiUrlSetting
= ConfigurationManager.AppSettings["ActiveCampaignApiUrl"];
Please make sure you reference System.Configuration, and include using System.Configuration; directive.
FYI: They return string value (not key value pair).
Ok so I have a better solution,
As I'm working with nopCommerce I need to use:
private readonly ISettingService _settingService = EngineContext.Current.Resolve<ISettingService>();
string apikey = _settingService.GetSettingByKey<string>("apikey_removed");
string apiurl = _settingService.GetSettingByKey<string>("apiurl_removed");
As outlined in this forum thread
Then in the administration backend under configuration > settings > all settings I add the key there.
This is a much better solution because if the api key or url ever need to be changed it can be done through the nopcommerce administration panel. rather than rebuilding/publishing the solution to a web server.
Hope this helps someone :)

Overwrite encrypted configuration section without decrypting?

When I try to access configuration section that is encrypted and cannot be decrypted properly (for example, someone just grabbed config file from another machine blindly) - Configuration class is throwing an exception. I want to catch that situation and rewrite the section completely in such case.
I've tried to remove and add back the section in question, but it seems that removal is ignored - second statement in 'catch' throws another exception about such section already exists:
try
{
// this getter might throw an exception - e.g. if encrypted on another machine
var connStrings = config.ConnectionStrings;
}
catch (ConfigurationException)
{
config.Sections.Remove("connectionStrings");
config.Sections.Add("connectionStrings", new ConnectionStringsSection());
}
It might be related to the fact I have connectionStrings section residing in separate file, i.e. my config file has something like <connectionStrings configSource="connections.config"/>, while actual encrypted content is in the connections.config file.
Is it possible to do what I need without falling back to direct XML manipulations, by using .NET Configuration classes only?
I'm pretty sure this will do what you want. In my case, I just included a bogus connectionString setting:
<connectionStrings>
<add connectionString="foo"/>
</connectionStrings>
I didn't include a "name" property, so trying to read ConnectionStrings will blow up, just like in your case:
try {
var x = ConfigurationManager.ConnectionStrings; //blows up
}
catch {
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Remove("connectionStrings");
config.Save(); //Now save the changes
ConfigurationManager.RefreshSection("connectionStrings"); //and reload the section
var x = ConfigurationManager.ConnectionStrings; //can now read!
}
You still won't be able to do this:
config.Sections.Add("connectionStrings", new ConnectionStringsSection());
Because (at least on my machine), it's picking up connectionStrings from the Machine.config.
I suspect though that in your case that's fine. You are now at a point where if you want to, you can add your own connection strings and you don't really need to completely blow away the connection string section.

How to change location of app.config

I want to change the location where my application looks for the app.config file.
I know that I can use ConfigurationManager.OpenExeConfiguration() to access an arbitrary config file - however, when the .Net Framework reads the config file (for ConnectionStrings or EventSources, for instance), it will look at the default location. I want to actually change the location, globally for the entire .Net Framework (for my application, of course).
I also know that I can use AppDomainSetup to change the location of the app.config for a new AppDomain. However, that doesn't apply to the primary AppDomain of the application.
I also know that I can override function Main() and create a new AppDomain as above and run my application in that new AppDomain. However, that has other side-effects - for instance, Assembly.GetEntryAssembly() will return a null reference.
Given how everything else works in .Net, I would expect there to be some way to configure the startup environment of my application - via a Application Manifest, or some such - but I have been unable to find even a glimmer of hope in that direction.
Any pointer would be helpful.
David Mullin
I used the approach with starting another AppDomain from Main(), specifying the "new" location of the configuration file.
No issues with GetEntryAssembly(); it only returns null, when being called from unmanaged code - or at least it doesn't for me, as I use ExecuteAssembly() to create/run the second AppDomain, much like this:
int Main(string[] args)
{
string currentExecutable = Assembly.GetExecutingAssembly().Location;
bool inChild = false;
List<string> xargs = new List<string>();
foreach (string arg in xargs)
{
if (arg.Equals("-child"))
{
inChild = true;
}
/* Parse other command line arguments */
else
{
xargs.Add(arg);
}
}
if (!inChild)
{
AppDomainSetup info = new AppDomainSetup();
info.ConfigurationFile = /* Path to desired App.Config File */;
Evidence evidence = AppDomain.CurrentDomain.Evidence;
AppDomain domain = AppDomain.CreateDomain(friendlyName, evidence, info);
xargs.Add("-child"); // Prevent recursion
return domain.ExecuteAssembly(currentExecutable, evidence, xargs.ToArray());
}
// Execute actual Main-Code, we are in the child domain with the custom app.config
return 0;
}
Note that we are effectively rerunning the EXE, just as a AppDomain and with a different config. Also note that you need to have some "magic" option that prevents this from going on endlessly.
I crafted this out from a bigger (real) chunk of code, so it might not work as is, but should illustrate the concept.
I am not sure why you want to change the location of your config file - perhaps there can be different approach for solving your actual problem. I had a requirement where I wanted to share configuration file across related applications - I had chosen to use own xml file as it had given me extra benefit of having complete control over the schema.
In your case, it's possible to externalize sections of your config file to a separate file using configSource property. See here under "Using External Configuration Files" to check how it has been done for connection strings section. Perhaps, this may help you.
var configPath = YOUR_PATH;
if (!Directory.Exists(ProductFolder))
{
Directory.CreateDirectory(ProductFolder);
}
if (!File.Exists(configPath))
{
File.WriteAllText(configPath, Resources.App);
}
var map = new ExeConfigurationFileMap
{
ExeConfigFilename = configPath,
LocalUserConfigFilename = configPath,
RoamingUserConfigFilename = configPath
};
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
Then use config member as you want.
Another approach is to leave the config file with the executable file and move the relevant changeable sections to external xml files which can be in whatever location you choose.
If you are using your config file in a readonly capacity, then you can add the relevant chunks to an XML file in a different location using XML Inlcude. This won't work if you are trying to write values back directly to app.config using the Configuration.Save method.
app.config:
<?xml version="1.0"?>
<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
<appSettings>
<xi:include href="AppSettings.xml"/>
</appSettings>
<connectionStrings>
<xi:include href="ConnectionStrings.xml"/>
</connectionStrings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/></startup>
</configuration>
ConnectionStrings.xml:
<?xml version="1.0"?>
<add name="Example1ConnectionString"
connectionString="Data Source=(local)\SQLExpress;Initial Catalog=Example1DB;Persist Security Info=True;User ID=sa;Password=password"
providerName="System.Data.SqlClient" />
<add name="Example2ConnectionString"
connectionString="Data Source=(local)\SQLExpress;Initial Catalog=Example2DB;Persist Security Info=True;User ID=sa;Password=password"
providerName="System.Data.SqlClient" />
AppSettings.xml:
<?xml version="1.0"?>
<add key="Setting1" value="Value1"/>
<add key="Setting2" value="Value2"/>
A file URI looks like this:
file:///C:/whatever.txt
You can even define failover files in case the one you are trying to reference is missing. This pattern is from https://www.xml.com/pub/a/2002/07/31/xinclude.html:
<xi:include href="http://www.whitehouse.gov/malapropisms.xml">
<xi:fallback>
<para>
This administration is doing everything we can to end the stalemate in
an efficient way. We're making the right decisions to bring the solution
to an end.
</para>
</xi:fallback>

web.config in asp.net

I've got the function for changing the values in web.config
but my problem is it is not getting the path of web.config correctly and throwing
"Could not find file 'C:\Users\maxnet25\Web.config'"
It was giving error on xmlDoc.Load() function.
My code:
public void UpdateConfigKey(string strKey, string newValue)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config");
if (!ConfigKeyExists(strKey))
{
throw new ArgumentNullException("Key", "<" + strKey + "> not find in the configuration.");
}
XmlNode appSettingsNode = xmlDoc.SelectSingleNode("configuration/appSettings");
foreach (XmlNode childNode in appSettingsNode)
{
if (childNode.Attributes["key"].Value == strKey)
childNode.Attributes["value"].Value = newValue;
}
xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config");
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
Label1 .Text ="Key Upated Successfullly";
}
What error messsage is being given?
Either way, you're not really going about modifying web.config in the right way. You should probably take a look at the System.Configuration.ConfigurationManager class as this provides programmatic access to the web.config file in a structured manner. Note that to access this class you need to add a reference to System.Configuration.dll to your project to bring the ConfigurationManager into scope.
If you look at the example code for the GetSection method, it shows how to create/add settings in the appSettings section of a .net config file, so that example should be enough to get you where you want to go.
If you definately want to use this approach to manipulate your web.config file, I suspect that:
AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config")
is incorrect, based on the path that you've shown in the error message. Try removing the ..\..\ and seeing if that works. AppDomain.CurrentDomain.BaseDirectory should be pointing at the location of your web.config file without modification.
Assuming this is indeed an ASP.NET website, instead of this:
AppDomain.CurrentDomain.BaseDirectory + "..\\..\\Web.config"
Use this:
HttpContext.Current.Server.MapPath("~/Web.config")
On a side note, please be aware that anytime you make a change to web.config, your web application restarts. You might not need to worry about that depending on what your web app does though.
Try using Server.MapPath() to resolve the location of your web.config. If you're in a page, Server is one of the page properties. If not, you can find it in HttpContext.Current.
As an example...
HttpContext.Current.Server.MapPath("~/web.config")
...should return the physical path to the web.config at the top of your web application.
Now, you're probably much better off using the WebConfigurationManager, as shown in this post. The approach is much cleaner, but requires a reference to System.Configuration.
Have you added a web.config to your web site?
You should use either:
System.Configuration.ConfigurationManager
for app.config files, or:
System.Web.Configuration.WebConfigurationManager
for web.config files.
You can actually use System.Configuration.ConfigurationManager with web.config files as well, and to be honest, I'm not actually sure if there's any benefit for using one over the other.
But either way, you should not be using the Xml namespaces and writing/modifying the raw XML.

Categories

Resources