How to get some elements from app.config in C#? - c#

Based on my app.config I would like to be able to get the elements of columns as shown in the example below in lines 3-5. How should I write the code in order to achieve this. If I'll need to change my app.config - I'll do it.
1. var bounceProviders = ConfigurationManager.GetSection("BounceProviders") as BounceProvidersSection;
2. var providerColumns = bounceProviders.Providers[0].Columns;
3. var emailColumn = providerColumns.Email;
4. var dateColumn = providerColumns.Date;
5. var messageColumn = providerColumns.Message;
app.config
<BounceProviders>
<Providers>
<Provider Name="p1">
<Columns>
<Email Name="My Email" />
<Date Name="My Date" />
<Message Name="My Message" />
</Columns>
</Provider>
<Provider Name="p2">
<Columns />
</Provider>
</Providers>
</BounceProviders>
ConfigurationSection
public class BounceProvidersSection : ConfigurationSection
{
[ConfigurationCollection(typeof(ConfigCollection<BounceProviderConfig>), AddItemName = "Provider")]
[ConfigurationProperty("Providers", IsRequired = true)]
public ConfigCollection<BounceProviderConfig> Providers
{
get { return (ConfigCollection<BounceProviderConfig>)this["Providers"]; }
set { this["Providers"] = value; }
}
}
public class BounceProviderConfig : ConfigurationElement
{
[ConfigurationProperty("Name", IsRequired = true)]
public string Name
{
get { return (string)this["Name"]; }
set { this["Name"] = value; }
}
}
ConfigCollection
public class ConfigCollection<T> : ConfigurationElementCollection
where T : ConfigurationElement, new()
{
protected override ConfigurationElement CreateNewElement()
{
return new T();
}
protected override object GetElementKey( ConfigurationElement element )
{
return element.GetHashCode();
}
public T this[int index]
{
get
{
return ( T )BaseGet( index );
}
set
{
if ( BaseGet( index ) != null )
{
BaseRemoveAt( index );
}
BaseAdd( index, value );
}
}
new public T this[string Name]
{
get
{
return ( T )BaseGet( Name );
}
}
}
sdf

I figured it out
public class BounceProvidersSection : ConfigurationSection
{
[ConfigurationCollection(typeof(ConfigCollection<BounceProviderConfig>), AddItemName = "Provider")]
[ConfigurationProperty("Providers", IsRequired = true)]
public ConfigCollection<BounceProviderConfig> Providers
{
get { return (ConfigCollection<BounceProviderConfig>)this["Providers"]; }
set { this["Providers"] = value; }
}
}
public class BounceProviderConfig : ConfigurationElement
{
[ConfigurationProperty("Id", IsRequired = true)]
public int Id
{
get { return (int)this["Id"]; }
set { this["Id"] = value; }
}
[ConfigurationProperty("Columns", IsRequired = false)]
public BounceProviderColumns Columns
{
get { return (BounceProviderColumns)this["Columns"]; }
set { this["Columns"] = value; }
}
public static BounceProviderConfig GetByProviderId(int providerId)
{
var section = ConfigUtils.GetConfigurationSection<BounceProvidersSection>("BounceProviders");
foreach (BounceProviderConfig provider in section.Providers)
{
if (provider.Id == providerId)
return provider;
}
return null;
}
}
public class BounceProviderColumns : ConfigurationElement
{
[ConfigurationProperty("Email", IsRequired = true)]
public ColumnConfig Email
{
get { return (ColumnConfig)this["Email"]; }
set { this["Email"] = value; }
}
[ConfigurationProperty("Date", IsRequired = true)]
public DateColumnConfig Date
{
get { return (DateColumnConfig)this["Date"]; }
set { this["Date"] = value; }
}
[ConfigurationProperty("Message", IsRequired = true)]
public ColumnConfig Message
{
get { return (ColumnConfig)this["Message"]; }
set { this["Message"] = value; }
}
}
public class ColumnConfig : ConfigurationElement
{
[ConfigurationProperty("Name", IsRequired = true)]
public string Name
{
get { return (string)this["Name"]; }
set { this["Name"] = value; }
}
}

Related

How to read custom object list from app.config

I've defined custom settings in app.config but I am getting an error when reading the section. It works with simple structure like reading only one profile but as soon as I have a list of profiles it fails with an error: "Unknown element "profile"". Can anyone tell me what am I doing wrong?
Here`s part of my app.config:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="DTester.Properties.ProfileSection" type="DTester.Settings.ProfileSection, DTester"/>
</configSections>
<DTester.Properties.ProfileSection>
<profiles>
<profile site="test1" urlscheme="http" urldomain="localhost">
<dataSource dataSource="test2" databaseName="test1" dbUserName="test1" dbUserPassword="test1" />
<user userName="test" password="test" TOHSoftwareVersion="8" iOSVersion="3" deviceUDID="12312"/>
</profile>
<profile site="test2" urlscheme="http" urldomain="localhost" >
<dataSource dataSource="test2" databaseName="test2" dbUserName="test2" dbUserPassword="test2" />
<user userName="test" password="test" TOHSoftwareVersion="3" iOSVersion="8" deviceUDID="123122"/>
</profile>
</profiles>
</DTester.Properties.ProfileSection>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
and here are my classes
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace DTester.Settings
{
public class Profile : ConfigurationElement
{
[ConfigurationProperty("profile")]
public ProfileElem profile
{
get
{
return this["profile"] as ProfileElem;
}
set
{
this["profile"] = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace DTester.Settings
{
[ConfigurationCollection(typeof(ProfileSection))]
public class ProfileCollection : ConfigurationElementCollection
{
public Profile this[int index]
{
get
{
return base.BaseGet(index) as Profile;
}
}
protected override ConfigurationElement CreateNewElement()
{
return new Profile();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Profile)(element)).profile.site;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace DTester.Settings
{
public class ProfileElem : ConfigurationElement
{
[ConfigurationProperty("site", IsRequired = true)]
public string site
{
get
{
return this["site"] as string;
}
set
{
this["site"] = value;
}
}
[ConfigurationProperty("urlscheme", IsRequired = true)]
public string urlscheme
{
get
{
return this["urlscheme"] as string;
}
set
{
this["urlscheme"] = value;
}
}
[ConfigurationProperty("urldomain", IsRequired = true)]
public string urldomain
{
get
{
return this["urldomain"] as string;
}
set
{
this["urldomain"] = value;
}
}
[ConfigurationProperty("dataSource", IsRequired = true)]
public DataSource dataSource
{
get
{
return this["dataSource"] as DataSource;
}
set
{
this["dataSource"] = value;
}
}
[ConfigurationProperty("user", IsRequired = true)]
public UserConfig user
{
get
{
return this["user"] as UserConfig;
}
set
{
this["user"] = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace DTester.Settings
{
public class DataSource : ConfigurationElement
{
[ConfigurationProperty("dataSource", IsRequired = true)]
public string dataSource
{
get
{
return this["dataSource"] as string;
}
set
{
this["dataSource"] = value;
}
}
[ConfigurationProperty("databaseName", IsRequired = true)]
public string databaseName
{
get
{
return this["databaseName"] as string;
}
set
{
this["databaseName"] = value;
}
}
[ConfigurationProperty("dbUserName", IsRequired = true)]
public string dbUserName
{
get
{
return this["dbUserName"] as string;
}
set
{
this["dbUserName"] = value;
}
}
[ConfigurationProperty("dbUserPassword", IsRequired = true)]
public string dbUserPassword
{
get
{
return this["dbUserPassword"] as string;
}
set
{
this["dbUserPassword"] = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
namespace DTester.Settings
{
public class UserConfig : ConfigurationElement
{
[ConfigurationProperty("userName", IsRequired = true)]
public string userName
{
get
{
return this["userName"] as string;
}
set
{
this["userName"] = value;
}
}
[ConfigurationProperty("password", IsRequired = true)]
public string password
{
get
{
return this["password"] as string;
}
set
{
this["password"] = value;
}
}
[ConfigurationProperty("TOHSoftwareVersion", IsRequired = true)]
public string TOHSoftwareVersion
{
get
{
return this["TOHSoftwareVersion"] as string;
}
set
{
this["TOHSoftwareVersion"] = value;
}
}
[ConfigurationProperty("iOSVersion", IsRequired = true)]
public string iOSVersion
{
get
{
return this["iOSVersion"] as string;
}
set
{
this["iOSVersion"] = value;
}
}
[ConfigurationProperty("deviceUDID", IsRequired = true)]
public string deviceUDID
{
get
{
return this["deviceUDID"] as string;
}
set
{
this["deviceUDID"] = value;
}
}
}
}
I used the this tool to get the respose https://nconfiggen.codeplex.com/wikipage?title=Example2&referringTitle=Home
Here`s the modified configuration section:
<DTesterConfiguration>
<option cmpResWithOacis="true" valRecentRosterPat="false" maxPatCount="1" maxResCount="3" maxDetCount="3" />
<profiles defaultProfile="test1">
<profile site="test1" urlscheme="http" urldomain="localhost">
<dataSource dataSource="test2" databaseName="test1" dbUserName="test1" dbUserPassword="test1" />
<user userName="test" password="test" TOHSoftwareVersion="dfdf" iOSVersion="dfdf" deviceUDID="dfdf"/>
</profile>
<profile site="test2" urlscheme="http" urldomain="localhost" >
<dataSource dataSource="test2" databaseName="test2" dbUserName="test2" dbUserPassword="test2" />
<user userName="test" password="test" TOHSoftwareVersion="dfdf" iOSVersion="dfdf" deviceUDID="dfdfdf"/>
</profile>
</profiles>
</DTesterConfiguration>
and here is the code:
public sealed class DTesterConfiguration
{
private static DTesterConfigurationSection _config;
static DTesterConfiguration()
{
_config = ((DTesterConfigurationSection)(global::System.Configuration.ConfigurationManager.GetSection("DTesterConfiguration")));
}
private DTesterConfiguration()
{
}
public static DTesterConfigurationSection Config
{
get
{
return _config;
}
}
}
public sealed partial class DTesterConfigurationSection : System.Configuration.ConfigurationSection
{
[System.Configuration.ConfigurationPropertyAttribute("profiles")]
[System.Configuration.ConfigurationCollectionAttribute(typeof(ProfilesElementCollection.ProfileElement), AddItemName = "profile")]
public ProfilesElementCollection Profiles
{
get
{
return ((ProfilesElementCollection)(this["profiles"]));
}
}
[System.Configuration.ConfigurationPropertyAttribute("option")]
//[System.Configuration.ConfigurationCollectionAttribute(typeof(OptionElement), AddItemName = "option")]
public OptionElement Option
{
get
{
return ((OptionElement)(this["option"]));
}
}
//<option cmpResWithOacis="true" valRecentRosterPat="false" maxPatCount="10" maxResCount="3" maxDetCount="3" />
public sealed partial class OptionElement : System.Configuration.ConfigurationElement
{
[System.Configuration.ConfigurationPropertyAttribute("cmpResWithOacis", IsRequired = true)]
public bool CmpResWithOacis
{
get
{
return ((bool)(this["cmpResWithOacis"]));
}
set
{
this["cmpResWithOacis"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("valRecentRosterPat", IsRequired = true)]
public bool ValRecentRosterPat
{
get
{
return ((bool)(this["valRecentRosterPat"]));
}
set
{
this["valRecentRosterPat"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("maxPatCount", IsRequired = true)]
public long MaxPatCount
{
get
{
return ((long)(this["maxPatCount"]));
}
set
{
this["maxPatCount"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("maxResCount", IsRequired = true)]
public long MaxResCount
{
get
{
return ((long)(this["maxResCount"]));
}
set
{
this["maxResCount"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("maxDetCount", IsRequired = true)]
public long MaxDetCount
{
get
{
return ((long)(this["maxDetCount"]));
}
set
{
this["maxDetCount"] = value;
}
}
}
public sealed partial class ProfilesElementCollection : System.Configuration.ConfigurationElementCollection
{
[System.Configuration.ConfigurationPropertyAttribute("defaultProfile", IsRequired = true)]
public string DefaultProfile
{
get
{
return ((string)(this["defaultProfile"]));
}
set
{
this["defaultProfile"] = value;
}
}
public ProfileElement this[int i]
{
get
{
return ((ProfileElement)(this.BaseGet(i)));
}
}
protected override System.Configuration.ConfigurationElement CreateNewElement()
{
return new ProfileElement();
}
protected override object GetElementKey(System.Configuration.ConfigurationElement element)
{
return ((ProfileElement)(element)).Site;
}
public sealed partial class ProfileElement : System.Configuration.ConfigurationElement
{
[System.Configuration.ConfigurationPropertyAttribute("site", IsRequired = true)]
public string Site
{
get
{
return ((string)(this["site"]));
}
set
{
this["site"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("urlscheme", IsRequired = true)]
public string Urlscheme
{
get
{
return ((string)(this["urlscheme"]));
}
set
{
this["urlscheme"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("urldomain", IsRequired = true)]
public string Urldomain
{
get
{
return ((string)(this["urldomain"]));
}
set
{
this["urldomain"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("dataSource")]
public DataSourceElement DataSource
{
get
{
return ((DataSourceElement)(this["dataSource"]));
}
}
[System.Configuration.ConfigurationPropertyAttribute("user")]
public UserElement User
{
get
{
return ((UserElement)(this["user"]));
}
}
public sealed partial class DataSourceElement : System.Configuration.ConfigurationElement
{
[System.Configuration.ConfigurationPropertyAttribute("dataSource", IsRequired = true)]
public string DataSource
{
get
{
return ((string)(this["dataSource"]));
}
set
{
this["dataSource"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("databaseName", IsRequired = true)]
public string DatabaseName
{
get
{
return ((string)(this["databaseName"]));
}
set
{
this["databaseName"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("dbUserName", IsRequired = true)]
public string DbUserName
{
get
{
return ((string)(this["dbUserName"]));
}
set
{
this["dbUserName"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("dbUserPassword", IsRequired = true)]
public string DbUserPassword
{
get
{
return ((string)(this["dbUserPassword"]));
}
set
{
this["dbUserPassword"] = value;
}
}
}
public sealed partial class UserElement : System.Configuration.ConfigurationElement
{
[System.Configuration.ConfigurationPropertyAttribute("userName", IsRequired = true)]
public string UserName
{
get
{
return ((string)(this["userName"]));
}
set
{
this["userName"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("password", IsRequired = true)]
public string Password
{
get
{
return ((string)(this["password"]));
}
set
{
this["password"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("TOHSoftwareVersion", IsRequired = true)]
public string TOHSoftwareVersion
{
get
{
return ((string)(this["TOHSoftwareVersion"]));
}
set
{
this["TOHSoftwareVersion"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("iOSVersion", IsRequired = true)]
public string IOSVersion
{
get
{
return ((string)(this["iOSVersion"]));
}
set
{
this["iOSVersion"] = value;
}
}
[System.Configuration.ConfigurationPropertyAttribute("deviceUDID", IsRequired = true)]
public string DeviceUDID
{
get
{
return ((string)(this["deviceUDID"]));
}
set
{
this["deviceUDID"] = value;
}
}
}
}
}
}

Cannot define more than one section in web.config

I want to have multiple sections in sectiongroup like this
**<CredentialsGroup>
<Credentials>
<company name="Carolina" userid="abc" password="dd"></company>
<file name="dfbf0f94-767e-4c71-b4ee-2dc05fb76e3c.csv"
url="https://e.brightree.net/Home/file.csv"></file>
<company name="Asbury" userid="abc" password="dde"></company>
<file name="dfbf0f94-767e-4c71-b4ee-2dc05fb76e3c.csv"
url="https://e.brightree.net/Home/file.csv"></file>
</Credentials>
</CredentialsGroup>**
and this is my customconfig File
**public class CredentialsSection: ConfigurationSection
{
[ConfigurationProperty("company",IsRequired=true)]
public CompanyElement Company
{
get {
return (CompanyElement)this["company"];
}
set
{
this["company"] = value;
}
}
[ConfigurationProperty("file",IsRequired=true)]
public FileElement File
{
get
{
return (FileElement)this["file"];
}
set
{
this["file"] = value;
}
}
}
public class CompanyElement : ConfigurationElement
{
[ConfigurationProperty("name",IsRequired=true)]
public string Name
{
get {
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("userid", IsRequired = true)]
public string UserId
{
get
{
return (string)this["userid"];
}
set
{
this["userid"] = value;
}
}
[ConfigurationProperty("password", IsRequired = true)]
public string Password
{
get
{
return (string)this["password"];
}
set
{
this["password"] = value;
}
}
}
public class FileElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("url",IsRequired=true)]
public string Url
{
get
{
return (string)this["url"];
}
set {
this["url"] = value;
}
}
}**
Company and File node shoukd be siblings and their selection will be conditional based on company name like this
ConfigurationManager.GetSection("CredentialsGroup/Credentials/company['name']=" + companyName);
Please Help

Custom Config Section .NET

I am trying to create a custom config section for holding some API credentials following the tutorial at: http://devlicio.us/blogs/derik_whittaker/archive/2006/11/13/app-config-and-custom-configuration-sections.aspx . I have added the following to my Web.config file:
<!-- Under configSections -->
<section name="providers" type="EmailApiAccess.Services.ProviderSection, EmailApiAccess.Services"/>
<!-- Root Level -->
<providers>
<add name="ProviderName" username="" password ="" host="" />
</providers>
and have created the following classes:
public class ProviderSection: ConfigurationSection
{
[ConfigurationProperty("providers")]
public ProviderCollection Providers
{
get { return ((ProviderCollection)(base["providers"])); }
}
}
[ConfigurationCollection(typeof(ProviderElement))]
public class ProviderCollection : ConfigurationElementCollection
{
public ProviderElement this[int index]
{
get { return (ProviderElement) BaseGet(index); }
set
{
if (BaseGet(index) != null)
BaseRemoveAt(index);
BaseAdd(index, value);
}
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ProviderElement)(element)).name;
}
protected override ConfigurationElement CreateNewElement()
{
return new ProviderElement();
}
}
public class ProviderElement: ConfigurationElement
{
public ProviderElement() { }
[ConfigurationProperty("name", DefaultValue="", IsKey=true, IsRequired=true)]
public string name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}
[ConfigurationProperty("username", DefaultValue = "", IsRequired = true)]
public string username
{
get { return (string)this["username"]; }
set { this["username"] = value; }
}
[ConfigurationProperty("password", DefaultValue = "", IsRequired = true)]
public string password
{
get { return (string)this["password"]; }
set { this["password"] = value; }
}
[ConfigurationProperty("host", DefaultValue = "", IsRequired = false)]
public string host
{
get { return (string)this["host"]; }
set { this["host"] = value; }
}
}
However, when I try and implement the code using this:
var section = ConfigurationManager.GetSection("providers");
ProviderElement element = section.Providers["ProviderName"];
var creds = new NetworkCredential(element.username, element.password);
I get an error saying that 'Object' does not contain a definition for 'Providers'....
Any help would be appreciated.
ConfigurationManager.GetSection returns a value of type object, not your custom config section. Try the following:
var section = ConfigurationManager.GetSection("providers") as ProviderSection;

Custom Configuration for app.config - collections of sections?

My head is absolutely pounding badly! I have done this before but not as "in depth" or complex as this and I have tried different ways to make this happen but all has failed.
So, this is the custom XML I want in the app.config:
<Profiles> <!--Collection-->
<Profile Name="Live">
<Components>
<Component Name="Portal" Type="Web" />
<Component Name="Comms" Type="Web" />
<Component Name="Scheduler" Type="WindowsService" ServiceName="LiveScheduler" />
</Components>
<Databases>
<Database Name="Main" Connection="Data Source=.\SQL2008" />
<Database Name="Staging" Connection="Data Source=SomeSite.co.uk" />
</Databases>
</Profile>
<Profile Name="Test">
<Components>
<Component Name="Portal" Type="Web" />
<Component Name="Comms" Type="Web" />
<Component Name="Scheduler" Type="WindowsService" ServiceName="TestScheduler" />
</Components>
<Databases>
<Database Name="Main" Connection="Data Source=.\SQL2008" />
<Database Name="Staging" Connection="Data Source=Internal" />
</Databases>
</Profile>
</Profiles>
So a collection of Profile with each profile having a collection of sub elements (Components is a collection, then Component is an element)
However I currently have all that EXCEPT for the multiple profiles. I kind of do see the problem but not sure how to "fix" it.
Code:
public class Profile : ConfigurationSection
{
[ConfigurationProperty("Name", IsRequired=true)]
public string Name
{
get
{
return base["Name"] as string;
}
set
{
base["Name"] = value;
}
}
[ConfigurationProperty("Components")]
public ComponentCollection Components
{
get { return ((ComponentCollection)(base["Components"])); }
}
[ConfigurationProperty("Databases")]
public DatabaseCollection Databases
{
get
{
return ((DatabaseCollection)(base["Databases"]));
}
}
}
[ConfigurationCollection(typeof(Component), AddItemName="Component")]
public class ComponentCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new Component();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Component)(element)).Name;
}
public Component this[int idx]
{
get
{
return base.BaseGet(idx) as Component;
}
set
{
if (base.BaseGet(idx) != null)
{
base.BaseRemoveAt(idx);
}
this.BaseAdd(idx, value);
}
}
public Component this[string key]
{
get
{
return base.BaseGet(key) as Component;
}
set
{
if (base.BaseGet(key) != null)
{
base.BaseRemove(key);
}
this.BaseAdd(this.Count, value);
}
}
}
public class Component : ConfigurationElement
{
[ConfigurationProperty("Type", IsRequired = true)]
public string Type
{
get
{
return this["Type"] as string;
}
set
{
this["Type"] = value;
}
}
[ConfigurationProperty("Name", IsRequired = true, IsKey = true)]
public string Name
{
get
{
return this["Name"] as string;
}
set
{
this["Name"] = value;
}
}
[ConfigurationProperty("ServiceName", IsRequired = false)]
public string ServiceName
{
get
{
return this["ServiceName"] as string;
}
set
{
this["ServiceName"] = value;
}
}
}
[ConfigurationCollection(typeof(Database), AddItemName = "Database")]
public class DatabaseCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new Database();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Database)(element)).Name;
}
public Database this[int idx]
{
get
{
return base.BaseGet(idx) as Database;
}
set
{
if (base.BaseGet(idx) != null)
{
base.BaseRemoveAt(idx);
}
this.BaseAdd(idx, value);
}
}
public Database this[string key]
{
get
{
return base.BaseGet(key) as Database;
}
set
{
if (base.BaseGet(key) != null)
{
base.BaseRemove(key);;
}
this.BaseAdd(this.Count, value);
}
}
}
public class Database : ConfigurationElement
{
[ConfigurationProperty("Name", IsKey = true, IsRequired = true)]
public string Name
{
get
{
return this["Name"] as string;
}
set
{
this["Name"] = value;
}
}
[ConfigurationProperty("Connection", IsKey = false, IsRequired = true)]
public string Connection
{
get
{
return this["Connection"] as string;
}
set
{
this["Connection"] = value;
}
}
}
You need to move your configuration section one level higher.
public class Profiles : ConfigurationSection
{
[ConfigurationProperty("Profile")]
public ProfileCollection Profile
{
get
{
return this["profile"] as ProfileCollection;
}
}
}
Here's a section that I created. You should be able to get yours working by following this:
public class ImportConfiguration : ConfigurationSection
{
[ConfigurationProperty("importMap")]
public ImportMapElementCollection ImportMap
{
get
{
return this["importMap"] as ImportMapElementCollection;
}
}
}
public class ImportColumnMapElement : ConfigurationElement
{
[ConfigurationProperty("localName", IsRequired = true, IsKey = true)]
public string LocalName
{
get
{
return this["localName"] as string;
}
set
{
this["localName"] = value;
}
}
[ConfigurationProperty("sourceName", IsRequired = true)]
public string SourceName
{
get
{
return this["sourceName"] as string;
}
set
{
this["sourceName"] = value;
}
}
}
public class ImportMapElementCollection : ConfigurationElementCollection
{
public ImportColumnMapElement this[object key]
{
get
{
return base.BaseGet(key) as ImportColumnMapElement;
}
}
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}
protected override string ElementName
{
get
{
return "columnMap";
}
}
protected override bool IsElementName(string elementName)
{
bool isName = false;
if (!String.IsNullOrEmpty(elementName))
isName = elementName.Equals("columnMap");
return isName;
}
protected override ConfigurationElement CreateNewElement()
{
return new ImportColumnMapElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ImportColumnMapElement)element).LocalName;
}
}
You're implementing correctly except you need one extra level. Change Profile from a ConfigurationSection to a ConfigurationElement, then make a ConfigurationSection Profiles that contains a collection of Profile items.
This is an excellent case for automated testing, debugging configuration sections without is a royal pain.

Custom config section containing collection

I'm having trouble getting a custom config section to work. It's some code I got from the web in an effort to try to understand this area a little better and enable me to get to where I want to ultimatly be, my own custom config section.
The error I get when I run the code in a console app is
'
Unrecognized attribute 'extension'. Note that attribute names are case-sensitive.'
The code in the main app to get things going is
var conf = ConfigurationManager.GetSection("uploadDirector");
and this is where the exception appears.
This is the config section I am hoping/trying to achieve
<AuthorisedClients>
<AuthorisedClient name="Client">
<Queue id="1" />
<Queue id="7" />
</AuthorisedClient>
<AuthorisedClient name="Client2">
<Queue id="3" />
<Queue id="4" />
</AuthorisedClient>
</AuthorisedClients>
Here's the code I have got from the web
.config file
<uploadDirector>
<filegroup name="documents" defaultDirectory="/documents/">
<clear/>
<add extension="pdf" mime="application/pdf" maxsize="100"/>
<add extension="doc" mime="application/word" maxsize="500"/>
</filegroup>
<filegroup name="images">
<clear/>
<add extension="gif" mime="image/gif" maxsize="100"/>
</filegroup>
</uploadDirector>
UploadDirectorConfigSection.cs
public class UploadDirectorConfigSection : ConfigurationSection {
private string _rootPath;
public UploadDirectorConfigSection() {
}
[ConfigurationProperty("rootpath", DefaultValue="/", IsRequired=false, IsKey=false)]
[StringValidator(InvalidCharacters=#"~!.##$%^&*()[]{};'\|\\")]
public string RootPath {
get { return _rootPath; }
set { _rootPath = value; }
}
[ConfigurationProperty("", IsRequired = true, IsKey = false, IsDefaultCollection = true)]
public FileGroupCollection FileGroups {
get { return (FileGroupCollection) base[""]; }
set { base[""] = value; }
}
}
FileGroupCollection.cs
public class FileGroupCollection : ConfigurationElementCollection {
protected override ConfigurationElement CreateNewElement() {
return new FileGroupElement();
}
protected override object GetElementKey(ConfigurationElement element) {
return ((FileGroupElement) element).Name;
}
public override ConfigurationElementCollectionType CollectionType {
get {
return ConfigurationElementCollectionType.BasicMap;
}
}
protected override string ElementName {
get {
return "filegroup";
}
}
protected override bool IsElementName(string elementName) {
if (string.IsNullOrWhiteSpace(elementName) || elementName != "filegroup")
return false;
return true;
}
public FileGroupElement this[int index] {
get { return (FileGroupElement) BaseGet(index); }
set {
if(BaseGet(index) != null)
BaseRemoveAt(index);
BaseAdd(index, value);
}
}
}
FileGroupElement.cs
public class FileGroupElement : ConfigurationElement {
[ConfigurationProperty("name", IsKey=true, IsRequired = true)]
[StringValidator(InvalidCharacters = #" ~.!##$%^&*()[]{}/;'""|\")]
public string Name {
get { return (string) base["name"]; }
set { base["name"] = value; }
}
[ConfigurationProperty("defaultDirectory", DefaultValue = ".")]
public string DefaultDirectory {
get { return (string) base["Path"]; }
set { base["Path"] = value; }
}
[ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)]
public FileInfoCollection Files {
get { return (FileInfoCollection) base[""]; }
}
}
FileInfoCollection.cs
public class FileInfoCollection : ConfigurationElementCollection {
protected override ConfigurationElement CreateNewElement() {
return new FileInfoCollection();
}
protected override object GetElementKey(ConfigurationElement element) {
return ((FileInfoElement) element).Extension;
}
}
FileInfoElement.cs
public class FileInfoElement : ConfigurationElement {
public FileInfoElement() {
Extension = "txt";
Mime = "text/plain";
MaxSize = 0;
}
[ConfigurationProperty("extension", IsKey = true, IsRequired = true)]
public string Extension {
get { return (string)base["extension"]; }
set { base["extension"] = value; }
}
[ConfigurationProperty("mime", DefaultValue = "text/plain")]
public string Mime {
get { return (string) base["mime"]; }
set { base["mime"] = value; }
}
[ConfigurationProperty("maxsize", DefaultValue = 0)]
public int MaxSize {
get { return (int) base["maxsize"]; }
set { base["maxsize"] = value; }
}
}
In your definition of FileInfoCollection in the method CreateNewElement you create FileInfoCollection which is wrong. Overridden CreateNewElement should return new collection element, not the new collection:
public class FileInfoCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new FileInfoElement();
}
protected override object GetElementKey (ConfigurationElement element)
{
return ((FileInfoElement)element).Extension;
}
}
Regarding your desired configuration, probably the simplest implementation will look like:
public class AuthorisedClientsSection : ConfigurationSection {
[ConfigurationProperty("", IsDefaultCollection = true)]
public AuthorisedClientElementCollection Elements {
get { return (AuthorisedClientElementCollection)base[""];}
}
}
public class AuthorisedClientElementCollection : ConfigurationElementCollection {
const string ELEMENT_NAME = "AuthorisedClient";
public override ConfigurationElementCollectionType CollectionType {
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override string ElementName {
get { return ELEMENT_NAME; }
}
protected override ConfigurationElement CreateNewElement() {
return new AuthorisedClientElement();
}
protected override object GetElementKey(ConfigurationElement element) {
return ((AuthorisedClientElement)element).Name;
}
}
public class AuthorisedClientElement : ConfigurationElement {
const string NAME = "name";
[ConfigurationProperty(NAME, IsRequired = true)]
public string Name {
get { return (string)base[NAME]; }
}
[ConfigurationProperty("", IsDefaultCollection = true)]
public QueueElementCollection Elements {
get { return (QueueElementCollection)base[""]; }
}
}
public class QueueElementCollection : ConfigurationElementCollection {
const string ELEMENT_NAME = "Queue";
public override ConfigurationElementCollectionType CollectionType {
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override string ElementName {
get { return ELEMENT_NAME; }
}
protected override ConfigurationElement CreateNewElement() {
return new QueueElement();
}
protected override object GetElementKey(ConfigurationElement element) {
return ((QueueElement)element).Id;
}
}
public class QueueElement : ConfigurationElement {
const string ID = "id";
[ConfigurationProperty(ID, IsRequired = true)]
public int Id {
get { return (int)base[ID]; }
}
}
And the test:
var authorisedClientsSection = ConfigurationManager.GetSection("AuthorisedClients")
as AuthorisedClientsSection;
foreach (AuthorisedClientElement client in authorisedClientsSection.Elements) {
Console.WriteLine("Client: {0}", client.Name);
foreach (QueueElement queue in client.Elements) {
Console.WriteLine("\tQueue: {0}", queue.Id);
}
}

Categories