Deepak Pathak
Deepak Pathak

Reputation: 646

Web.config - Custom configuration to hold a collection inside a collection

I am setting up a custom configuration in web.config using <configSections></configSections>.

The structure of tags which I want and created in web.config is:

<TwitterCredentialsSectionGroup>
    <TwitterCredentialsSection>
      <accounts>
        <account id="ID1">
          <add key="ConsumerKey" value="..."/>
          <add key="ConsumerSecretKey" value="..."/>
          <add key="AccessToken" value="..."/>
          <add key="AccesstSecretToken" value="..."/>
        </account>
      </accounts>
    </TwitterCredentialsSection>
  </TwitterCredentialsSectionGroup>

I registered my custom config section inside configSections tag using below tag:

<configSections>
<sectionGroup name="TwitterCredentialsSectionGroup">
  <section name="TwitterCredentialsSection" type="TwitterIntegration.TwitterCredentialsSection"
           allowLocation="true" allowDefinition="Everywhere" />
</sectionGroup>

Here there are 2 different collection elements namely:

  1. Account(holding each twitter account keys)
  2. Accounts(which will hold all twitter Account instances/tags)

Now my code file for custom configuration goes like this:

namespace TwitterIntegration
{
    public class TwitterCredentialsSection : ConfigurationSection
    {

    [ConfigurationProperty("accounts")]
    public AccountCollection Accounts
    {
        get
        {
            return (AccountCollection)this["accounts"];
        }
    }

    [ConfigurationProperty("account")]
    public AccountElement Account
    {
        get
        {
            return (AccountElement)this["account"];
        }
    }
}


public class TwitterKeyElement : ConfigurationElement
{
    [ConfigurationProperty("key",IsKey=true, IsRequired=true)]
    public String Key
    {
        get
        {
            return (String)this["key"];
        }
    }

    [ConfigurationProperty("value")]
    public String Value
    {
        get
        {
            return (String)this["value"];
        }
    }
}


[ConfigurationCollection(typeof(TwitterKeyElement))]
public class AccountElement : ConfigurationElementCollection
{
    [ConfigurationProperty("id", IsRequired = true, IsKey = true)]
    public string ID
    {
        get
        {
            return (string)this["id"];
        }
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new TwitterKeyElement();
    }
    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((TwitterKeyElement)element).Key;
    } 
}


[ConfigurationCollection(typeof(AccountElement))]
public class AccountCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new AccountElement();
    }
    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((AccountElement)element).ID;
    }


}

}

Now when I try to read the web.config, using below code, I get an error:

TwitterCredentialsSection objtcsection = (ConfigurationManager.GetSection("TwitterCredentialsSectionGroup/TwitterCredentialsSection") as TwitterCredentialsSection);

ERROR: **Parser Error Message: Unrecognized element 'account'.

Source Error: 


Line 19:     <TwitterCredentialsSection>
Line 20:       <accounts>
Line 21:         <account id="ID1"> 
Line 22:           <add key="ConsumerKey" value="W0SKMPuXzml2CHGsMSoHZA"/>
Line 23:           <add key="ConsumerSecretKey" value="kaAS0CgeQqcTWjTvYsie8Owtl8o6N8hcOclY9bKlu4"/> 
**

Can anyone please suggest what is wrong with my code?

Thanks

Upvotes: 1

Views: 1153

Answers (1)

wingmsr
wingmsr

Reputation: 5

Your code only needed two small changes:

  1. Add a ConfigurationCollection attribute to the Accounts property in your TwitterCredentialsSection class in order to define the unrecognized 'account' element:

    public class TwitterCredentialsSection : ConfigurationSection
    {
       [ConfigurationProperty("accounts")]
       [ConfigurationCollection(typeof(AccountCollection), AddItemName = "account")]
       public AccountCollection Accounts
       {
           get { return (AccountCollection) this["accounts"]; }
       }
    }
    
  2. Remove the Account property from the same TwitterCredentialsSection class:

    [ConfigurationProperty("account")]
    public AccountElement Account
    {
        get { return (AccountElement) this["account"]; }
    }
    

Upvotes: 0

Related Questions