I have a custom ConfigurationSection
that contains a custom ConfigurationElementCollection
with custom ConfigurationElement
instances. The <add>
and <clear>
tags work fine in the configuration file, but using <remove>
generates the following exception during my unit test:
System.Configuration.ConfigurationErrorsException: Unrecognized attribute 'name'. Note that attribute names are case-sensitive.
The configuration file is pretty simple. Here's the inner-part of the test section in question:
<exceptionHandling>
<policies>
<clear />
<add name="default" shouldLog="true" shouldShow="true"/>
<add name="initialization" shouldLog="true" shouldShow="true"/>
<add name="security" shouldLog="true" shouldShow="true"/>
<add name="logOnly" shouldLog="true" shouldShow="false"/>
<add name="unhandled" shouldLog="true" shouldShow="true"/>
<add name="test" shouldLog="false" shouldShow="false"/>
<remove name="test"/>
</policies>
</exceptionHandling>
The following is the relevant code for the configuration classes (some has been elided for brevity).
public sealed class ExceptionHandlingSection : ConfigurationSection
{
[ConfigurationProperty("policies", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(PolicyElementCollection), AddItemName = "add", RemoveItemName = "remove", ClearItemsName = "clear")]
public PolicyElementCollection Policies => (PolicyElementCollection)base["policies"];
}
public sealed class PolicyElementCollection : ConfigurationElementCollection
{
// pretty boiler plate
}
public sealed class PolicyElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get => (string)this["name"];
set => this["name"] = value;
}
// other properties
}
What needs to be done to get <remove>
to work as shown in the test configuration file?
The answer to this turns out to be really simple.
I read a few things talking about XML attributes, but fundamentally it's looking for a key property. This can be assigned by a property of the ConfigurationPropertyAttribute
. To get the <remove>
tag to work all I need to do is change my ConfigurationElement
class as follows:
public sealed class PolicyElement : ConfigurationElement
{
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
{
get => (string)this["name"];
set => this["name"] = value;
}
// other properties
}