c# Solution when keys in web.config can increase

Hi Experts,

I can have any number of following keys in web.config

<add key="WebServer1Logs" value="C:\meetDinesh"/>
<add key="WebServer2Logs" value="C:\meetDinesh"/>
<add key="WebServer3Logs" value="C:\meetDinesh"/>
<add key="WebServer4Logs" value="C:\meetDinesh"/>

The key format will remain same i.e. next will be WebServer5Logs

I want to read every key using some way so if more keys are added in future, I don't need to change the c# code to read them.

I believe this can be done with Regex can you share that regex.

or some other way also exists.
Dinesh KumarAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Lokesh B RDeveloperCommented:
Hi,

try this code to get all the keys from the AppSettings

var list = System.Configuration.ConfigurationManager.AppSettings.AllKeys
                             .Where(key => key.StartsWith("WebServer")).Select((item, index) => new
                             {
                                 key = item,
                                 Value = System.Configuration.ConfigurationManager.AppSettings[item]

                             }).ToList();

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ste5anSenior DeveloperCommented:
It's imho a misuse of the key-value concept here, cause the keys should be known at compile time.

I would use my own section handler to get better semantics:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>    
    <section name="serverLogs" type="ConsoleCS.ServerLogsHandler,ConsoleCS"/>    
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <serverLogs>
    <serverLog displayName="Server 1" serverName="server-1" path="c:\Temp\Server-1" />          
    <serverLog displayName="Server 2" serverName="server-2" path="c:\Temp\Server-2" />
    <serverLog displayName="Server 3" serverName="server-3" path="c:\Temp\Server-3" />
  </serverLogs>
</configuration>

Open in new window


and

namespace ConsoleCS
{
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Xml;

    class Program
    {
        static void Main(string[] args)
        {
            List<ServerLog> serverLogs =  (List<ServerLog>)ConfigurationSettings.GetConfig("serverLogs");
            serverLogs.ConsoleWriteLine();
            Console.WriteLine("Done.");
            Console.ReadLine();
        }
    }

    public class ServerLog
    {
        public string DisplayName { get; set; }
        public string ServerName { get; set; }
        public string Path { get; set; }

        public override string ToString()
        {
            return string.Format("{0}: {1} - {0}", this.DisplayName, this.ServerName, this.Path);
        }
    }    

    public class ServerLogsHandler : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            List<ServerLog> result = new List<ServerLog>();
            foreach (XmlNode childNode in section.ChildNodes)
            {
                ServerLog serverLog = new ServerLog();
                serverLog.DisplayName = childNode.Attributes["displayName"].Value;
                serverLog.DisplayName = childNode.Attributes["serverName"].Value;
                serverLog.DisplayName = childNode.Attributes["path"].Value;
                result.Add(serverLog);
            }

            return result;
        }
    }

    public static class ListExtension
    {
        public static void ConsoleWriteLine<T>(this List<T> list)
        {
            foreach (T item in list)
            {
                Console.WriteLine(item);
            }
        }
    }
}

Open in new window

Dinesh KumarAuthor Commented:
1. cause the keys should be known at compile time  can you explain it more.

2. instead of writing so much code as you mentioned, Don't you think I can apply the regex on Webconfig
    only thing the worry is web.config at Server may be not available for READ when site goes live.
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

ste5anSenior DeveloperCommented:
1, This is my personal opinon:
In a config file we should only specify known keys to get self-explaining semantics. Compare

<add key="WebServer1Logs" value="C:\meetDinesh"/>
<add key="WebServer2Logs" value="C:\meetDinesh"/>
<add key="WebServer3Logs" value="C:\meetDinesh"/>
-- vs
<serverLogs>
  <serverLog displayName="Server 1" serverName="server-1" path="c:\Temp\Server-1" />          
  <serverLog displayName="Server 2" serverName="server-2" path="c:\Temp\Server-2" />
  <serverLog displayName="Server 3" serverName="server-3" path="c:\Temp\Server-3" />
</serverLogs>

Open in new window


My approach has a stronger semantic meaning. Here we have much lesser to explain. Especially we tell the user (administrator) what he is actually configuring by using meaningful tags. This is better than your approach. For example consider the user (administrator) does not know what those values mean, then he needs to search for key and value in your code. Also it is not clear that you use other key-value pairs to configure something completely different then logs. Only controlled by the content of a name.
In my case he has already a clue from the tag and searching will not be ambiguous.

2. Much more code? Really? The code I have to write more is:

    public class ServerLog
    {
        public string DisplayName { get; set; }
        public string ServerName { get; set; }
        public string Path { get; set; }

        public override string ToString()
        {
            return string.Format("{0}: {1} - {0}", this.DisplayName, this.ServerName, this.Path);
        }
    }    

    public class ServerLogsHandler : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            List<ServerLog> result = new List<ServerLog>();
            foreach (XmlNode childNode in section.ChildNodes)
            {
                ServerLog serverLog = new ServerLog();
                serverLog.DisplayName = childNode.Attributes["displayName"].Value;
                serverLog.DisplayName = childNode.Attributes["serverName"].Value;
                serverLog.DisplayName = childNode.Attributes["path"].Value;
                result.Add(serverLog);
            }

            return result;
        }
    }

Open in new window


It covers two simple classes in some 30 lines. And C# is object oriented. These classes are small, simple to read and maintain.

Also you get better semantics in your code. Cause you don't need to work with dynamic/anonymous objects, but you can use speaking objects instead (serverLog.Path and serverLog.ServerName vs var.Key and var.Value).

Basically it's about using structure over convention and getting bindable semantics on all levels at compile time. Better to catch an error when compiling, then when running a program.
Dinesh KumarAuthor Commented:
Thanks ste5an..
Dinesh KumarAuthor Commented:
this task is deferred to future so will need time to respond on this.
Dinesh KumarAuthor Commented:
Thanks Experts for your valuable time and answers.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.