read standard Properties.Settings from config file

In a C# project, there is a handy 'Settings' section in the Project, where you can easily add in settings.

Unfortunately, there does not seem to be an easy way to READ the settings.

If you use the provided types, you will actually be reading for what I think is a user-specific config file, that is normally not present.  An example of a provided type is:

 Properties.Settings.Default.rdlcLocation  

note: the above may work if the config file is located under %APPDATA% ?

I'm pretty sure I used the above on a couple of ClickOnce projects, which always run from underneath %APPDATA%.

__________________________

So, here is some code, that reads from the MyDLLName.dll.config file, and from the standard sections that are created by the 'Settings' editor on the C# project.

This means that the only editing you need to do on your config file, is changing the values.
No need to add in new sections to the config file.

An example of the standard sections:

 <?xml version="1.0" encoding="utf-8" ?> 

 <configuration> 

   <configSections> 

     <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > 

       <section name="WebConfigLibrary.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 

     </sectionGroup> 

   </configSections> 

 ... 

 ... 

   <applicationSettings> 

     <WebConfigLibrary.Properties.Settings> 

       <setting name="rdlcLocation" serializeAs="String"> 

         <value>C:\sourceroot\eLicensing\Libraries\WebReportsLibrary\reports\RDLCs</value> 

       </setting> 

     </WebConfigLibrary.Properties.Settings> 

   </applicationSettings> 

  </configuration>  


Here is the code:  ( for a DLL named WebConfigLibrary.dll - so its config file is WebConfigLibrary.dll.config )

note: this works for a Windows Forms application + for a ASP.NET application.



 using System; 

 using System.Collections.Generic; 

 using System.Text; 

 using System.Configuration; 

 using System.Xml; 

 using System.IO; 

 using System.Diagnostics; 

 using System.Web; 

 namespace WebConfigLibrary 

 { 

   public enum ESetting { eLicensing_WEB, rdlcLocation }; 

   /// <summary> 

   /// simple class to provide one interface, to access the settings in WebConfig.config 

   ///  

   /// idea is to have 1 config file for each environment. 

   /// e.g. WebConfig.dev.config, WebConfig.live.config

   ///  

   /// </summary> 

   public class WebConfig 

   { 

     public static string GetSetting(ESetting setting) 

     { 

       //make sure that we load the config file WebConfigLibrary.dll.config 

       //a curse on Mr Gates !!! 

       //the .Default values point to some user-specific location which is of little use 99% of the use cases for config files ! 

       XmlDocument xmlDoc = new XmlDocument(); 

       xmlDoc.Load(getConfigFile("WebConfigLibrary.dll.config")); 

       switch (setting) 

       { 

         case ESetting.eLicensing_WEB: 

           return getConnectionStringSettingFromConfig(xmlDoc, "WebConfigLibrary.Properties.Settings.eLicensing_WEB"); 

         case ESetting.rdlcLocation: 

           return getSettingFromConfig(xmlDoc, "rdlcLocation"); 

         default: 

           throw new NotImplementedException("The setting " + setting + " is not recognised"); 

       } 

     } 

     private static string getConfigFile(string configFile) 

     { 

       //first try the location of this DLL: 

       string pathToConfigFile = Path.Combine(Path.GetDirectoryName(typeof(WebConfig).Assembly.Location), configFile); 

       if(File.Exists(pathToConfigFile)) 

         return pathToConfigFile; 

       //now try the root of the ASP.NET site: 

       pathToConfigFile = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, configFile); 

       if(File.Exists(pathToConfigFile)) 

         return pathToConfigFile; 

       throw new ConfigurationException("cannot locate the config file " + configFile); 

     } 

     private static string getConnectionStringSettingFromConfig(XmlDocument xmlDoc, string cxnStringName) 

     { 

       string xpath = string.Format("/configuration/connectionStrings/add[@name='{0}']", cxnStringName); 

       XmlNode nodeAdd = xmlDoc.SelectSingleNode(xpath); 

       foreach(XmlAttribute attr in nodeAdd.Attributes) 

       { 

         if (attr.Name == "connectionString") 

         { 

           return attr.Value; 

         } 

       } 

       Debug.Assert(false); 

       return ""; 

     } 

     private static string getSettingFromConfig(XmlDocument xmlDoc, string attrName) 

     { 

       string xpathFormat = "/configuration/applicationSettings/WebConfigLibrary.Properties.Settings/setting[@name='{0}']"; 

       string xpath = string.Format(xpathFormat, attrName); 

       XmlNode node = xmlDoc.SelectSingleNode(xpath); 

       return node.FirstChild.FirstChild.Value; 

     } 

   } 

 }  


_________________________
appendix:

here is another more standard way to read from config file:




     static bool checkRequiredFields() 
     {
       NameValueCollection appConfig = ConfigurationManager.AppSettings;
       if (string.IsNullOrEmpty(appConfig["AWSAccessKey"]))
       {
         Console.WriteLine("AWSAccessKey was not set in the App.config file.");
         return false;
       }  


Comments