March 2, 2021
Hot Topics:

Creating an Application Development Framework Using Enterprise Templates - Part 1

  • By Thiru Thangarathinam
  • Send Email »
  • More Articles »

Custom Configuration section handling classes

Before the arrival of .NET, we used to store global configuration settings such as connection strings in a centralized location like registry. But in the .NET world, all these global settings are stored in the application configuration file that is normally deployed along with the application code. For an ASP.NET web application, it will be web.config file and for a WinUI application, it will be app.config.

For example, the following appSettings entry in the web.config file can be used to store the connection string.

<configuration>  <appSettings>    <add key="connectionstring"    value="server=localhost;database=Northewind;uid=sa;pwd=;"/>  </appSettings></configuration>

We can read the above connection string from our code by using the following statement.

string connString = new ConfigurationSettings.AppSettings["connectionString"];

This simple key/value mechanism (stored in the appSettings section) is perfect for many common needs, such as storing database connection strings at application scope; but it's not flexible enough for more complex data. As you can see, the data that is stored in the appSetttings section is in plain text, which renders it unfit for storing settings such as connection strings to the database and so on.

Fortunately, Microsoft also built in a mechanism for creating custom configuration classes that can be used to represent data in the configuration files. Rather than reading a hard-coded list of tags recognized only via code within a specific application, the .NET framework can also read one or more configSections (that define the tag names) and then use that information to identify blocks of information in the remainder of the configuration file. Before we look at the example application that implements the custom configuration section handling classes, let us understand the theory behind custom configuration sections. Custom configuration sections are placed into two main areas in the configuration file.

  • A configuration section declaration area- This is identified by the configSections element. For example, to create a configuration section named appConfigSection, we need to place the following settings within the web.config file.
<configuration>   <configSections><section    name="appConfigSection"    type="DistributedApp.AppFramework.ConfigurationHandler.ApplConfigSectionHandler,ConfigurationHandler"></section>  </configSections>   ..  ..</configuration>

As you can see from the above, we use the type attribute to specify the section handler class (that implements the IConfigurationSectionHandler interface) that will be automatically invoked, when the application tries to read the configuration information using the System.Configuration.ConfigurationSettings.GetConfig method. We will see the implementation of the ApplConfigSectionHandler class in a moment.

  • Configuration section settings area — This is the area where the actual configuration settings are stored. For example, in the following declaration we define the section settings under the appConfigSection element.
<?xml version="1.0" encoding="utf-8" ?><configuration>  ..  ..     <appConfigSection>    <appSection name="loggingSection" encrypted="true"><appSetting key="loggingEnabled" value="true"></appSetting>          </appSection>    </appConfigSection></configuration>

As shown above, we also have an attribute named encrypted in the appSection element that allows us to indicate to the configuration helper methods if the settings are encrypted. If the encrypted attribute is set to true, then the configuration helper method will decrypt the values before returning it to the caller. The encryption and decryption capabilities are available in the class library named Encryption, which is explained in the following section.

The code for the class that implements the custom configuration handler is as follows:

public class ApplConfigSectionHandler : IConfigurationSectionHandler{  public ApplConfigSectionHandler()  {  }  public Object Create(Object parent, Object input, XmlNode node)  {    XmlNodeList appSectionNodes;    XmlNodeList appSettings;    NameValueCollection arrAppSetting;    ArrayList arrSettings = new ArrayList();    string name;    string sname;    string svalue;    string encrypted = "false";      appSectionNodes = node.SelectNodes("appSection");//Loop through all the AppSection nodes and add them to the ArrayList    foreach(XmlNode appSectionNode in appSectionNodes)    {      arrAppSetting = new NameValueCollection();name = appSectionNode.Attributes.GetNamedItem("name").Value;XmlNode encryptedAttr = appSectionNode.Attributes.GetNamedItem("encrypted");      if (encryptedAttr != null)        encrypted = encryptedAttr.Value;      appSettings = appSectionNode.SelectNodes("appSetting");      if (appSettings != null)      {//Loop through all the appSetting elements and add them to the arraylist        foreach(XmlNode appSetting in appSettings)        {          sname = appSetting.Attributes["key"].Value;svalue = appSetting.Attributes["value"].Value;          arrAppSetting.Add(sname, svalue);        }      }arrSettings.Add(new AppSection(name, arrAppSetting,encrypted));    }    //Return the constructed object to the caller    return arrSettings;  }}

In the above code, we basically loop through all the elements in the custom configuration section and add it to an array list of that contains all the settings in the form of AppSection objects. The AppSection class that is used to encapsulate every subsection in the custom configuration section is defined as follows:

public class AppSection{  private string _name;  private NameValueCollection _appSettings;  private string _encrypted;public AppSection(string name, NameValueCollection appSettings, string encrypted)  {    _name = name;    _appSettings = appSettings;    _encrypted = encrypted;  }  public string Name  {    get    {      return _name;    }  }  public string GetValue(string key)  {    string keyValue = null;    if ( _appSettings !=null)    {//Get the corresponding value from the NameValueCollection      keyValue = _appSettings[key.Trim()];      if (_encrypted == "true")      {  byte[] encryptedText = Encoding.ASCII.GetBytes(keyValue);        Decryptor dec = new Decryptor();        byte[] plainText = dec.Decrypt(encryptedText);        keyValue = Convert.ToBase64String(plainText);      }    }                          return keyValue;  }    }

The GetValue method in the AppSection class is where the check for decryption is performed. If the encrypted attribute returns true, then the method decrypts the encrypted settings by invoking the Decrypt method of the Decryptor class.

Page 4 of 5

This article was originally published on May 23, 2003

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date