2

I would like to implement a custom configuration section in a project. But something I don't understand so dont work.

I have App.config that looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="DepartmentConfigurationSection" type="Statistics.Config.DepartmentSection , Program1"/>
  </configSections>
  <s>
    <Cash>
      <add Number="1" Name="Money" />
    </Cash>
    <Departments>
      <add Id="1" Name="x" />
      <add Id="2" Name="y" />
    </Departments>
  </s>
</configuration>

I create a file called DepartmentSection.cs that cointains the ConfigurationElement,ConfigurationElementCollection and the ConfigurationSection. The class is like this:

 public class DepartmentConfig : ConfigurationElement
    {
        public DepartmentConfig() { }

        public DepartmentConfig(int id, string name)
        {
            Id = id;
            Name = name;
        }

        [ConfigurationProperty("Id", IsRequired = true, IsKey = true)]
        public int Id
        {
            get { return (int)this["Id"]; }
            set { this["Id"] = value; }
        }

        [ConfigurationProperty("Name",  IsRequired = true, IsKey = false)]
        public string Name
        {
            get { return (string)this["Name"]; }
            set { this["Name"] = value; }
        }
    }


    public class DepartmentCollection : ConfigurationElementCollection
    {
        public DepartmentCollection()
        {
            Console.WriteLine("ServiceCollection Constructor");
        }

        public DepartmentConfig this[int index]
        {
            get { return (DepartmentConfig)BaseGet(index); }
            set
            {
                if (BaseGet(index) != null)
                {
                    BaseRemoveAt(index);
                }
                BaseAdd(index, value);
            }
        }

        public void Add(DepartmentConfig depConfig)
        {
            BaseAdd(depConfig);
        }

        public void Clear()
        {
            BaseClear();
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return new DepartmentConfig();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((DepartmentConfig)element).Id;
        }

        public void Remove(DepartmentConfig depConfig)
        {
            BaseRemove(depConfig.Id);
        }

        public void RemoveAt(int index)
        {
            BaseRemoveAt(index);
        }

        public void Remove(string name)
        {
            BaseRemove(name);
        }
    }


    public class DepartmentConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("Departments", IsDefaultCollection = false)]
        [ConfigurationCollection(typeof(DepartmentCollection),
            AddItemName = "add",
            ClearItemsName = "clear",
            RemoveItemName = "remove")]
        public DepartmentCollection Departments
        {
            get
            {
                return (DepartmentCollection)base["Departments"];
            }
        }
    }

I tried to get the collection from the handler but without success. I tried like this but give me this error: "Unable to initialize the system configuration".

    DepartmentConfigurationSection serviceConfigSection =
    ConfigurationManager.GetSection("s") as DepartmentConfigurationSection;

    DepartmentConfig serviceConfig = serviceConfigSection.Departments[0];

2 Answers 2

3

The problems appear to be in your app.config (or web.config). The element that contains your custom configuration XML must match the name you have specified in the name attribute in configSections\section. For example, for your code to work as written, the app.config should look something like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="s" type="Statistics.Config.DepartmentConfigurationSection, Program1"/>
  </configSections>
  <s>
    <Cash>
      <add Number="1" Name="Money" />
    </Cash>
    <Departments>
      <add Id="1" Name="x" />
      <add Id="2" Name="y" />
    </Departments>
  </s>
</configuration>

As you can see, the section name="s" matches the name of the s element. Also, you had the type listed as Statistics.Config.DeptartmentSection, but your class name is DepartmentConfigurationSection, so it should match the class you are trying to load.

Sign up to request clarification or add additional context in comments.

7 Comments

I corrected the errors but now appares this: " Error while creating the configuration section handler for s: Could not load type 'Program1.Config.DepartmentConfigurationSection' from assembly 'Program1'... Why?
That means there's no class Program1.Config.DepartmentConfigurationSection in the Program1 assembly. What namespace is DepartmentConfigurationSection under? The type attribute should be type="[namespace], [assembly]", so in your case I think that should be type="Statistics.Config.DepartmentConfigurationSection, Program1".
The namespace is namespace Statistics.Config. What you mean when said no class in the Program1 assembly ?
If the namespace is Statistics.Config, then the fully qualified name of the class is Statistics.Config.DepartmentConfigurationSection. The name of the assembly is Program1. So the type attribute should read type="Statistics.Config.DepartmentConfigurationSection, Program1".
I meant what I said, there's no class named Program1.Config.DepartmentConfigurationSection in the Program1 assembly. The class is named Statistics.Config.DepartmentConfigurationSection. :)
|
1

I think you need to add class-level attribute at DepartmentCollection class with :

[DepartmentCollection(typeof(DepartmentConfig ), AddItemName = "add", CollectionType = ConfigurationElementCollectionType.BasicMap)]

1 Comment

Please elaborate why you think this is a solution. Just code answers do bring a solution, but not understanding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.