Search code examples
c#asp.netconfigurationsectioncustom-configurationconfigurationelement

Weird error while accessing an element in a ConfigurationElementCollection


I have a ConfigurationSection with a ConfigurationElementCollection like below:

    <MyConfiguration hostUrl="https://example.com/ewe/rets">
        <sampleConfig userName="xzxzxzxzxzx" password="00000000" listName="MyList">
          <metadata>
            <add name="folderName" value="TestFolder"/>
            <add name="fileName" value="TestFileName" />
            <add name="title" value="TestTitle" />
            <add name="description" value="TestDescription" />
          </metadata>
        </sampleConfig>
        <whateverConfig userName="xzxzxzxzxzx" password="00000000" listName="MyList">
          <metadata>
            <add name="siteName" value="TestFolder"/>
            <add name="fileName" value="TestFileName" />
            <add name="title" value="TestTitle" />
            <add name="description" value="TestDescription" />
          </metadata>
        </whateverConfig>
</MyConfiguration>

and the code looks like this:

    public sealed class MyConfiguration: ConfigurationSection
    {
            [ConfigurationProperty("hostUrl", IsRequired = true)]
            public string HostUrl
            {
                get { return (string)base["hostUrl"]; }
                set { base["hostUrl"] = value; }
            }

            [ConfigurationProperty("sampleConfig", IsRequired = true)]
            public ApiConfig SampleConfig
            {
                get { return (ApiConfig)base["sampleConfig"]; }
                set { base["sampleConfig"] = value; }
            }

            [ConfigurationProperty("whateverConfig", IsRequired = true)]
            public ApiConfig WhateverConfig
            {
                get { return (ApiConfig)base["whateverConfig"]; }
                set { base["whateverConfig"] = value; }
            }
    }

        public class ApiConfig : ConfigurationElement
        {
            [ConfigurationProperty("userName", IsRequired = true)]
            public string UserName
            {
                get { return (string)base["userName"]; }
                set { base["userName"] = value; }
            }

            [ConfigurationProperty("password", IsRequired = true)]
            public string Password
            {
                get { return (string)base["password"]; }
                set { base["password"] = value; }
            }

            [ConfigurationProperty("listName", IsRequired = true)]
            public string ListName
            {
                get { return (string)base["listName"]; }
                set { base["listName"] = value; }
            }

                    [ConfigurationProperty("metadata", IsDefaultCollection = false)]
            [ConfigurationCollection(typeof(MetadataCollection),
                AddItemName = "add",
                ClearItemsName = "clear",
                RemoveItemName = "remove")]
            public MetadataCollection MetaData
            {
                get
                {
                    return (MetadataCollection)base["metadata"];
                }
            }
    }

public class MetadataCollection : ConfigurationElementCollection
    {
        public MetadataConfig this[string key]
        {
            get { return (MetadataConfig)BaseGet(key); }
            set
            {
                if (BaseGet(key) != null)
                {
                    BaseRemove(key);
                }
                BaseAdd(value);
            }
        }

        public void Add(MetadataConfig metadataConfig)
        {
            BaseAdd(metadataConfig);
        }

        public void Clear()
        {
            BaseClear();
        }

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

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((MetadataConfig)element).SharePointName;
        }

        public void Remove(MetadataConfig element)
        {
            BaseRemove(element.SharePointName);
        }

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

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

    }

public class MetadataConfig : ConfigurationElement
    {
        [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
        public string Name
        {
            get { return (string)base["name"]; }
            set { base["name"] = value; }
        }

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

But when I try to access the "description" metadata, I get a NullReferenceException. This is because config.SampleConfig.Metadata["description"] is always null. But in the debug window, I can see that "Metadata" has 4 elements and "description" is there.

This is also true while accessing "title". But "folderName" and "fileName" are fine!!!

I am not sure whats wrong and I am banging my head at this for the last 4 hours!

Please help me out here.

Thanks.


Solution

  • Changing GetElementKey to:

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((MetadataConfig)element).Name;
    }
    

    Allows the following to return: TestTitle

    Console.WriteLine(serviceConfigSection.SampleConfig.MetaData["title"].Value);