In a web application, I want to be able to define some mapping using a config section like this:
<configuration>
<configSections>
<sectionGroup name="MyCustomer">
<section name="CatalogMappings" type="MyCustom.MyConfigSection" />
</sectionGroup>
</configSections>
<MyCustomer>
<catalogMappings>
<catalog name="toto">
<mapping value="1" displayText="titi" />
<mapping value="2" displayText="tata" />
</catalog>
<catalog name="toto2">
<mapping value="1" displayText="titi2" />
<mapping value="2" displayText="tata2" />
</catalog>
</catalogMappings>
</MyCustomer>
</configuration>
I'm struggling to achieve this goal, especially when defining my collection of collections. What are the classes that I need to implement to achieve this?
Currently, I have:
public class CatalogMappingSection : System.Configuration.ConfigurationSection
{
public class Mapping : ConfigurationElement
{
[ConfigurationProperty("externalKey")]
public string ExternalKey { get; set; }
[ConfigurationProperty("displayText", IsRequired=true)]
public string DisplayText { get; set; }
[ConfigurationProperty("value", IsRequired=true, IsKey=true)]
public int Value { get; set; }
}
public class Catalog : ConfigurationElementCollection
{
[ConfigurationProperty("name", IsRequired=true, IsKey=true)]
public string Name { get; set; }
protected override ConfigurationElement CreateNewElement()
{
return new Mapping();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Mapping)element).Value;
}
}
public class CatalogCollection : ConfigurationElementCollection
{
[ConfigurationProperty("catalog")]
[ConfigurationCollection(typeof(Catalog))]
public Catalog CatalogMappingCollection
{
get
{
return (Catalog)base["catalog"];
}
}
protected override ConfigurationElement CreateNewElement()
{
return new Catalog();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Catalog)element).Name;
}
}
[ConfigurationProperty("catalogMappings")]
[ConfigurationCollection(typeof(CatalogCollection))]
public CatalogCollection CatalogMappings
{
get
{
return (CatalogCollection)base["catalogMappings"];
}
}
}
But, this is not working as expected.
Due to the popularity of my other answer, I've written a custom example using Usa-States and Usa-Counties. An example that's a tad easier to follow.
I've also added some interfaces, which allows some mocking for unit-tests, something I wasn't fully aware of when I wrote this original answer.
I also added putting the settings in its own file, so your app.config file doesn't have a billion things in it.
I've also added a "Finder" to encapsulate searching for a specific item in the collection.
I've also added a custom Enum.
"UsaStatesSettings.config" (make sure you mark this as "copy-always")
The "app.config"
and now the "code"
I finally found this guy's example. It was coded and worked right out of the box.
http://manyrootsofallevilrants.blogspot.com/2011/07/nested-custom-configuration-collections.html
I am going to paste the code here......only because I cannot stand it when someone says "Your answer is here", and the link is dead.
Please try his website first, and leave a "thank you" if it works.