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.

Community
  • 1
  • 1
Zac Seth
  • 2,742
  • 5
  • 37
  • 56
  • You'll have to post the code where you create the configurationSection, as that's what's causing the error – Jonesopolis Apr 16 '14 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. – Zac Seth Apr 17 '14 at 10:33
  • Did you solve this? I have exactly the same problem (btw, Im not related to the other Jones :) – Jonesie Feb 19 '15 at 22:47
  • 1
    No, I never did. We ended up abandoning the child config concept in the end... – Zac Seth Feb 21 '15 at 15:27

0 Answers0