user1108948
user1108948

Reputation:

ConfigurationErrorsException occurred

I want to create a custom configuration for C# application. The app.config likes:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="location" type ="FolderConfigSection.LocationConfig, FolderConfigSection"/>
  </configSections>
  <location>
    <folders>
      <add folder ="C:\Test1"/>
      <add folder ="C:\Test2" />
      <add folder ="C:\Test3" />
    </folders>
  </location>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

So I created two classes.

namespace FolderConfigSection
{
    public class LocationConfig : ConfigurationSection
    {
        [ConfigurationProperty("folders")]
        public string Folder
        {
            get { return base["folder"] as string; }
            set { base["folder"] = value; }
        }
    }
}

And

namespace FolderConfigSection
{
    public class FolderCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new FolderElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((FolderElement)element).Environment;
        }
    }

    public class FolderElement : ConfigurationElement
    {
        [ConfigurationProperty("folder", IsRequired = true)]
        public string Environment
        {
            get { return (string)this["folder"]; }
            set { this["folder"] = value; }
        }
    }
}

But I got an exception in my Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        LocationConfig _locationConfig = (LocationConfig)ConfigurationManager.GetSection("location");
        string firstFolder = _locationConfig.Folder;

    }
}

The exception is The section name 'location' is reserved for <location> sections. Also I want to list all folders.

Upvotes: 0

Views: 114

Answers (1)

IronGeek
IronGeek

Reputation: 4883

I'm restating what @Tim has answered in his comments.

  1. Do not use location as section name. It is already reserved for <location> element configuration. Just use other name, such as locationConfig.
  2. Change the type of Folder property in LocationConfig class from String to FolderCollection. For clarity, you should probably change the property name Folder to its plural form Folders.
  3. To list all the folders in LocationConfig, you just need to iterate the Folders collection property. You might also want to implement indexer on FolderCollection class, for an indexed access to Folders property, .

Putting it all in code:

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="locationConfig" type ="FolderConfigSection.LocationConfig, FolderConfigSection"/>
  </configSections>
  <locationConfig>
    <folders>
      <add folder ="C:\Test1"/>
      <add folder ="C:\Test2" />
      <add folder ="C:\Test3" />
    </folders>
  </locationConfig>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

LocationConfig

namespace FolderConfigSection
{
  using System.Configuration;

  public class LocationConfig : ConfigurationSection
  {
    // Change the property type to FolderCollection, and
    // change the property name to `Folders` for clarity
    [ConfigurationProperty("folders")]
    public FolderCollection Folders
    {

      get { return base["folders"] as FolderCollection; }

      // the setter property isn't really needed here
      // set { base["folders"] = value; }
    }
  }

  public class FolderCollection : ConfigurationElementCollection
  {
    protected override ConfigurationElement CreateNewElement()
    {
      return new FolderElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
      return ((FolderElement)element).Environment;
    }

    // indexer
    public FolderElement this[int index]
    {
      get { return BaseGet(index) as FolderElement; }      
    }
  }

  public class FolderElement : ConfigurationElement
  {
    [ConfigurationProperty("folder", IsRequired = true)]
    public string Environment
    {
      get { return (string)this["folder"]; }
      set { this["folder"] = value; }
    }
  }
}

Program.cs

public class Program
{
  static void Main(string[] args)
  {
    var locationConfig = (LocationConfig)ConfigurationManager.GetSection("locationConfig");

    foreach (FolderElement folder in locationConfig.Folders)
    {
      // List all folders
      Console.WriteLine(folder.Environment);        
    }    

    // The first folder using indexer property
    Console.WriteLine(locationConfig.Folders[0].Environment);
  }
}

Upvotes: 2

Related Questions