Custom Configuration Collection - Unrecognized element 'addService'

6.8k views Asked by At

Example from MSDN on making a custom config section that should work as follows,

class RemoteServiceSection : ConfigurationSection
{
    [ConfigurationProperty("remoteServices", IsDefaultCollection=false)]
    [ConfigurationCollection(typeof(RemoteServiceCollection), AddItemName="addService", ClearItemsName="clearServices",
        RemoveItemName="removeService")]
    public RemoteServiceCollection Services
    {
        get
        {
            return this["remoteServices"] as RemoteServiceCollection; 
        }
    }
}

class RemoteServiceCollection : ConfigurationElementCollection, IList<RemoteServiceElement>
{
    public RemoteServiceCollection()
    {
        RemoteServiceElement element = (RemoteServiceElement)CreateNewElement();
        Add(element); 
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get
        {
            return ConfigurationElementCollectionType.AddRemoveClearMap;
        }
    }

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

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((RemoteServiceElement)element).Hostname;
    }

    protected override string ElementName
    {
        get
        {
            return "remoteService";
        }
    }

    public new IEnumerator<RemoteServiceElement> GetEnumerator()
    {
        foreach (RemoteServiceElement element in this)
        {
            yield return element; 
        }
    }

    public void Add(RemoteServiceElement element)
    { 
        BaseAdd(element, true); 
    }

    public void Clear()
    {
        BaseClear(); 
    }

    public bool Contains(RemoteServiceElement element)
    {
        return !(BaseIndexOf(element) < 0); 
    }

    public void CopyTo(RemoteServiceElement[] array, int index)
    {
        base.CopyTo(array, index); 
    }

    public bool Remove(RemoteServiceElement element)
    {
        BaseRemove(GetElementKey(element));
        return true; 
    }

    bool ICollection<RemoteServiceElement>.IsReadOnly
    {
        get { return IsReadOnly(); } 
    }

    public int IndexOf(RemoteServiceElement element)
    {
        return BaseIndexOf(element); 
    }

    public void Insert(int index, RemoteServiceElement element)
    {
        BaseAdd(index, element); 
    }

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

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

class RemoteServiceElement : ConfigurationElement
{
    public RemoteServiceElement() { }

    public RemoteServiceElement(string ip, string port)
    {
        this.IpAddress = ip;
        this.Port = port; 
    }

    [ConfigurationProperty("hostname", IsKey = true, IsRequired = true)]
    public string Hostname
    {
        get
        {
            return (string)this["hostname"];
        }
        set
        {
            this["hostname"] = value;
        }
    }
    [ConfigurationProperty("ipAddress", IsRequired = true)]
    public string IpAddress
    {
        get
        {
            return (string)this["ipAddress"];
        }
        set
        {
            this["ipAddress"] = value;
        }
    }
    [ConfigurationProperty("port", IsRequired = true)]
    public string Port
    {
        get
        {
            return (string)this["port"];
        }
        set
        {
            this["port"] = value;
        }
    }
}

}

I am getting the error that says 'Unrecognized element 'addService'. I think I've followed the MSDN article exactly. It can be found here - http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx

Thanks in advance for your help. This is what I wrote in app.config (with brackets of course that dont show up here?):

 <remoteServices>
   <addService hostname="xxxxxxx" ipAddress="xxx.x.xxx.xx" port="xxxx" >
 </remoteServices>

Here is app.config as requested, x'ing out the specific names just for privacy purposes, they are just strings:

<configuration>
<configSections>
  <section name="remoteServices" type="AqEntityTests.RemoteServiceSection, 
     AqEntityTests" allowLocation="true" allowDefinition="Everywhere"/>
  </configSections>
  <remoteServices>
   <addService hostname="xxxxxx.xxxxxxx.com" 
            ipAddress="xxx.x.xxx.xx" 
            port="xx" />
  </remoteServices>
2

There are 2 answers

0
DirectionUnkown On

For future generations:

Your config should look like this:

<configuration>
  <configSections>
    <section name="remoteServices" type="AqEntityTests.RemoteServiceSection, 
        AqEntityTests" allowLocation="true" allowDefinition="Everywhere"/>
  </configSections>

  <remoteServices>
    <remoteServices>
      <addService hostname="xxxxxx.xxxxxxx.com" 
         ipAddress="xxx.x.xxx.xx" 
         port="xx" />
    </remoteServices>
  </remoteServices>
</configuration>

Why?

You add to node:

<configSections> 

custom section named:

name="remoteServices"

with type

type="AqEntityTests.RemoteServiceSection

and then in code, you add property to your custom section:

[ConfigurationProperty("remoteServices", IsDefaultCollection=false)]

Meaning you created node inside node with both having same name. Because of that you have received error "Unrecognized element 'addService'". Just compiler informing you that such element should not be in that node.

Two links for quick learning of custom configuration:
Custom Configuration Sections for Lazy Coders
How to create sections with collections

0
Almund On

You might also look into using an unnamed default collection as I mention here

That allows you to add items in the manner you suggest.