views:

375

answers:

3

Am trying to implement a generic way for reading sections from a config file. The config file may contain 'standard' sections or 'custom' sections as below.

<configuration> 
<configSections>
 <section name="NoteSettings" type="System.Configuration.NameValueSectionHandler"/>
</configSections> 
<appSettings>
 <add key="AutoStart" value="true"/>
 <add key="Font" value="Verdana"/>
</appSettings> 
<NoteSettings>
 <add key="Height" value="100"/>
 <add key="Width" value="200"/>
</NoteSettings>

The method that I tried is as follows :

    private string ReadAllSections()
    {
        StringBuilder configSettings = new StringBuilder();

        Configuration configFile = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);

        foreach (ConfigurationSection section in configFile.Sections)
        {
            configSettings.Append(section.SectionInformation.Name);
            configSettings.Append(Environment.NewLine);                

            if (section.GetType() == typeof(DefaultSection))
            {
                NameValueCollection sectionSettings = ConfigurationManager.GetSection(section.SectionInformation.Name) as NameValueCollection;

                if (sectionSettings != null)
                {
                    foreach (string key in sectionSettings)
                    {
                        configSettings.Append(key);
                        configSettings.Append(" : ");
                        configSettings.Append(sectionSettings[key]);
                        configSettings.Append(Environment.NewLine);
                    }
                }
            }

            configSettings.Append(Environment.NewLine);
        }

        return configSettings.ToString();
    }

Assuming that all custom sections will have only KEY-VALUE

  • Is such an implementation possible? And if yes, is there a 'cleaner' and more elegant solution than this one?
  • The above method also reads 'invisible' sections like mscorlib, system.diagnostics. Is this avoidable?
  • System.Data.Dataset returns a dataset which could not be cast to a NameValueCollection. How can this be handled?

Corrections/suggestions welcome.

Thanks.

+1  A: 

Read your config into a XmlDocument then use XPath to find the elements your looking for?

Something like;

XmlDocument doc = new XmlDocument();
doc.Load(HttpContext.Current.Server.MapPath("~/web.config"));

XmlNodeList list = doc.SelectNodes("//configuration/appSettings");

foreach (XmlNode node in list[0].ChildNodes)

...

Dead account
A: 

Since configuration file is XML file, you can use XPath queries for this task:

    Configuration configFile = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
    XmlDocument document = new XmlDocument();
    document.Load(configFile.FilePath);
    foreach (XmlNode node in document.SelectNodes("//add"))
    {
        string key = node.SelectSingleNode("@key").Value;
        string value = node.SelectSingleNode("@value").Value;
        Console.WriteLine("{0} = {1}", key, value);
    }

If you need to get all {key, value} pair then you need to define triplets of XPath queries: 1 - main query for selecting nodes with similar structure. 2, 3 - queries for extracting key and value nodes from nodes retrieved by first query. In your case it's enough to have common query for all nodes, but it's easy to maintain support for different custom sections.

Dmitriy Matveev
A: 

When you've specified the NameValueSectionHandler as the type attribute for a section and call to Configuration.GetSection(string), you will receive a DefaultSection instance as the return type.

string SectionInformation.SectionInformation.GetRawXml() is the key in this case to get into your data.

I answered another similar question with a valid way to do it using System.Configuration that you can reference to get all the details and a code snippet. NameValueSectionHandler can i use this section type for writing back to the app

JJS