2

The Problem

I have a custom configuration section with a nested configuration collection. I have moved the main custom configuration section to its own file as so:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="my.section" type="My.App.CustomSection, My.App" />
  </configSections>
  <my.section configSource="app\custom.config" />
</configuration

and for app\custom.config:

<?xml version="1.0" encoding="utf-8"?>
<my.section>
  <children>
    <child configSource="children\child1.config" />
  </children>
</my.section>

And my children file at app\children\child1.config:

<?xml version="1.0" encoding="utf-8"?>
<child name="myChild">
  ...
</child>

In app\custom.config the <children> element is implemented as a ConfigurationElementCollection and works if the child elements are in-lined, but I'm seeing an exception with the message "Unrecognized attribute 'configSource'. Note that attribute names are case-sensitive." on the <child configSource="children\child1.config" /> line in the custom.config file.

The Question

Is it possible to use the configSource attribute for elements in a child of a config collection? If so, what might I be doing wrong here?

For now, I'll use in-lined children - however it would be very useful to be able to use custom config sources in our situation so any answer will be much appreciated.

Notes

NOTE 1: In case my paths were wrong I've also tried making the path relative to the root web.config and even moving all of the configs to the root folder - this had no effect on the error.

NOTE 2: I have read this question and ensured that I meet the conditions specified in the accepted (and only) answer - my config files are being output in the bin folder and they all have the appropriate <?xml version="1.0" encoding="utf-8" ?> declaration.

UPDATE:

As requested in the comments by Jonesy, the ConfigurationSection code:

public class CustomSection : ConfigurationSection
{
    private static readonly ConfigurationPropertyCollection properties;
    private static readonly ConfigurationProperty children;

    static CustomSection()
    {
        children = new ConfigurationProperty( 
            "children", 
            typeof( ChildSectionCollection ), 
            null, 
            ConfigurationPropertyOptions.IsRequired
        );

        properties = new ConfigurationPropertyCollection
        {
            children
        };
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return properties; }
    }

    [ConfigurationProperty( "children", IsRequired = true )]
    public ChildSectionCollection ChildrenSection
    {
        get { return ( ChildSectionCollection ) base[ children ]; }
    }
}

and:

public class ChildSection : ConfigurationSection
{
    private static readonly ConfigurationPropertyCollection properties;
    private static readonly ConfigurationProperty name;

    static ChildSection()
    {
        name = new ConfigurationProperty( 
            "name", 
            typeof( string ), 
            string.Empty, 
            ConfigurationPropertyOptions.IsRequired
        );

        properties = new ConfigurationPropertyCollection
        {
            name
        };
    }

    [ConfigurationProperty( "name", IsRequired = true )]
    public string Name
    {
        get { return ( string ) base[ name ]; }
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return properties; }
    }
}

and:

[ConfigurationCollection( typeof( ChildSection ), CollectionType = ConfigurationElementCollectionType.BasicMap, AddItemName = "child" )]
public class ChildSectionCollection : ConfigurationElementCollection
{
    private static readonly ConfigurationPropertyCollection properties;

    static ChildSectionCollection()
    {
        properties = new ConfigurationPropertyCollection();
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return properties; }
    }

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

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

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

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

and, lastly:

var customSection = ( CustomSection ) ConfigurationManager.GetSection( "my.section" );

NOTE 3: The design of my code is based upon Jon Rista's CodeProject article Unraveling the Mysteries of .NET 2.0 Configuration.

4
  • You'll have to post the code where you create the configurationSection, as that's what's causing the error Commented Apr 16, 2014 at 12:25
  • @Jonesy done. I've renamed all of the relevant types to make it general as well as removing non-relevant pieces of code - but what remains is an accurate example of the situation. Commented Apr 17, 2014 at 10:33
  • Did you solve this? I have exactly the same problem (btw, Im not related to the other Jones :) Commented Feb 19, 2015 at 22:47
  • 1
    No, I never did. We ended up abandoning the child config concept in the end... Commented Feb 21, 2015 at 15:27

0

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.