In a recent project, I used the web.config file to store some configuration settings that could easily be modified without redeploying code. I used the standard appSettings in <configurations><appSettings><add key=”” value=”” /> . This works great when you have a specific key name and value. For one specific setting, I needed a little more flexibility. I created a custom section in the web.config and the handler to read that section. Let me show you how.
Step 1
Define the xml markup needed by your custom section. Think about all the options and attributes needed by each item. You can have required and optional attributes along with default values.
<!--section--> <medGroupConfigs> <!--collection--> <medGroups> <!--elements--> <add name="Med Group 1" queryString="medical-group-one" username="MGO-001" /> <add name="Med Group 1" queryString="medical-group-1" username="MGO-001" password="abcdef"/> <add name="Med Group 2" queryString="medical-group-two" username="MGO-002" /> </medGroups> </medGroupConfigs>
Step 2
Create the handler to read the custom xml.
using System.Configuration; namespace MyConfig { //This class reads the defined config section (if available) and stores it locally in the static _Config variable. //This config data is available by calling MedGroups.GetMedGroups(). public class MedGroups { public static MedGroupConfigsSection _Config = ConfigurationManager.GetSection("medGroupConfigs") as MedGroupConfigsSection; public static MedGroupElementCollection GetMedGroups() { return _Config.MedGroups; } } //Extend the ConfigurationSection class. Your class name should match your section name and be postfixed with "Section". public class MedGroupConfigsSection : ConfigurationSection { //Decorate the property with the tag for your collection. [ConfigurationProperty("medGroups")] public MedGroupElementCollection MedGroups { get { return (MedGroupElementCollection)this["medGroups"]; } } } //Extend the ConfigurationElementCollection class. //Decorate the class with the class that represents a single element in the collection. [ConfigurationCollection(typeof(MedGroupElement))] public class MedGroupElementCollection : ConfigurationElementCollection { public MedGroupElement this[int index] { get { return (MedGroupElement)BaseGet(index); } set { if (BaseGet(index) != null) BaseRemoveAt(index); BaseAdd(index, value); } } protected override ConfigurationElement CreateNewElement() { return new MedGroupElement(); } protected override object GetElementKey(ConfigurationElement element) { return ((MedGroupElement)element).Name; } } //Extend the ConfigurationElement class. This class represents a single element in the collection. //Create a property for each xml attribute in your element. //Decorate each property with the ConfigurationProperty decorator. See MSDN for all available options. public class MedGroupElement : ConfigurationElement { [ConfigurationProperty("name", IsRequired = true)] public string Name { get { return (string)this["name"]; } set { this["name"] = value; } } [ConfigurationProperty("queryString", IsRequired = true)] public string QueryString { get { return (string)this["queryString"]; } set { this["queryString"] = value; } } [ConfigurationProperty("username", IsRequired = true)] public string Username { get { return (string)this["username"]; } set { this["username"] = value; } } [ConfigurationProperty("password", IsRequired = false, DefaultValue="12345")] public string Password { get { return (string)this["password"]; } set { this["password"] = value; } } } }
Step 3
Declare the handler at the top of the web.config file.
<configSections> <section name="medGroupConfigs" type="MyConfig.MedGroupConfigsSection"/> </configSections>
Step 4
Use the data from the custom section in your code.
//Look through the web.config/medGroupConfigs to find a matching queryString attribute foreach (MedGroupElement mg in MedGroups.GetMedGroups()) { if (string.Compare(medGroup, mg.QueryString) == 0) { uname = mg.username; } }
Complete web.config
Here is the complete web.config file for a more complete picture.
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="medGroupConfigs" type="MyConfig.MedGroupConfigsSection"/> </configSections> <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" /> </appSettings> <medGroupConfigs> <medGroups> <add name="Med Group 1" queryString="medical-group-one" username="MGO-001" /> <add name="Med Group 1" queryString="medical-group-1" username="MGO-001" password="abcdef"/> <add name="Med Group 2" queryString="medical-group-two" username="MGO-002" /> </medGroups> </medGroupConfigs> <system.web> <compilation debug="true" targetFramework="4.5.2" /> <httpRuntime targetFramework="4.5.2" /> </system.web> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" /> <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> <system.codedom> <compilers> <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral" /> </compilers> </system.codedom> </configuration>
This is exactly I was looking for! To the point, easy to follow post! This saved me a lot of time!
Thank you.
Cheers!
BD
Thanks for the comment! I’m glad it worked for you and saved you some time. Happy coding!
I was a bit confused with the naming convention. I thought was connected to public class MedGroupConfigsSection, but it’s connected to public class MedGroups.