The problem is, as the title say I get an exception whenever I try to load a custom CustomConfiguration section from my .config file. The app.config file I try to load looks like this.
....
<configSections>
<sectionGroup name="MainSection">
...
<section name="Directories" type="MyNamespace.DirectoriesSettings, Assembly"/>
</sectionGroup>
</configSections>
....
<MainSection>
...
<Directories Count="1">
<Directory id="1" Path="Some\Path" Working="And\Another\Path" Country="US"/>
</Directories>
</MainSection>
....
And the code
namespace MyNamespace
{
internal class DirectoriesSettings : ConfigurationSection
{
[ConfigurationProperty("Count")]
public int Count { get { return Convert.ToInt32(base["Count"]); } }
[ConfigurationProperty("Directories", IsDefaultCollection = true, IsRequired = true)]
[ConfigurationCollection(typeof(DirectoryElement), AddItemName = "Directory", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public DirectoryElementCollection Directories { get { return (DirectoryElementCollection)base["Directories"]; } }
}
internal class DirectoryElementCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new DirectoryElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((DirectoryElement)element).Id;
}
}
internal class DirectoryElement : ConfigurationElement
{
[ConfigurationProperty("id", IsKey = true, IsRequired = true)]
public int Id
{
get { return Convert.ToInt32(this["id"]); }
set { this["id"] = value; }
}
[ConfigurationProperty("Path", IsKey = false, IsRequired = true)]
public string Path
{
get { return Convert.ToString(this["Path"]); }
set { this["Path"] = value; }
}
[ConfigurationProperty("Working", IsKey = false, IsRequired = true)]
public string Working
{
get { return Convert.ToString(this["Working"]); }
set { this["Working"] = value; }
}
[ConfigurationProperty("Country", IsKey = false, IsRequired = true)]
public string Country
{
get { return Convert.ToString(this["Country"]); }
set { this["Country"] = value; }
}
}
}
And the code to use it
class SettingsContainer
{
private const string PARENT_SECTION = "MainSection";
...
private DirectoriesSettings _directoriesSettings;
public DirectoriesSettings Directories { get { return _directoriesSettings; } }
...
public SettingsContainer()
{
...
_directoriesSettings = (DirectoriesSettings)ConfigurationManager.GetSection(string.Format("{0}/Directories", PARENT_SECTION));
...
}
}
The exception (Unrecognized element 'Directory') is thrown whenever I try to set the _directoriesSettings variable.
I think I am doing it right, but apparently I am missing something.
Any help will be greatly appreciated.
Solution:
I found where my problem was.
The property Directories inside DirectoriesSettings class should look like this
[ConfigurationCollection(typeof(DirectoryElement), AddItemName = "Directory", CollectionType = ConfigurationElementCollectionType.BasicMap)]
[ConfigurationProperty("", IsDefaultCollection = true, IsRequired = true)]
public DirectoryElementCollection Directories { get { return (DirectoryElementCollection)this[""]; } }
instead of
[ConfigurationCollection(typeof(DirectoryElement), AddItemName = "Directory", CollectionType = ConfigurationElementCollectionType.BasicMap)]
[ConfigurationProperty("Directories", IsDefaultCollection = true, IsRequired = true)]
public DirectoryElementCollection Directories { get { return (DirectoryElementCollection)base["Directories"]; } }
Related
I am getting Entry has already been added error when trying to use same title for SubModule. It is happening even though IsKey = false but still it is not allowing to enter duplicate Upload as Title
How can I fix this issue?
Here's my web.config
<SiteModules>
<Modules>
<MainModule title="MyUpload">
<SubModule title="Upload" page="/script/upload1" groups="group1" display="true" type="maker"></SubModule>
<SubModule title="Upload" page="/script/upload2" groups="group2" display="true" type="checker"></SubModule>
<SubModule title="SomeTitle1" page="/script/upload3" groups="group1" display="false"></SubModule>
</MainModule>
</Modules>
</SiteModules>
Here's my class
namespace MyClasses
{
public class SiteModules : ConfigurationSection
{
[ConfigurationProperty("Modules", IsDefaultCollection = false)]
public Modules Modules
{
get
{
Modules modulesConfigElement = (Modules)base["Modules"];
return modulesConfigElement;
}
}
}
public class Modules : ConfigurationElementCollection
{
public Modules()
{
AddElementName = "MainModule";
}
protected override ConfigurationElement CreateNewElement()
{
return new MainModule();
}
protected override Object GetElementKey(ConfigurationElement element)
{
return ((MainModule)element).Title;
}
}
public class MainModule : ConfigurationElementCollection
{
public MainModule()
{
AddElementName = "SubModule";
}
[ConfigurationProperty("title", IsRequired = true, IsKey = false)]
public string Title
{
get
{
return (string)this["title"];
}
set
{
this["title"] = value;
}
}
protected override ConfigurationElement CreateNewElement()
{
return new SubModule();
}
protected override Object GetElementKey(ConfigurationElement element)
{
return ((SubModule)element).Title;
}
}
public class SubModule : ConfigurationElement
{
[ConfigurationProperty("title", IsRequired = true, IsKey = false)]
public string Title
{
get
{
return (string)this["title"];
}
set
{
this["title"] = value;
}
}
[ConfigurationProperty("page", IsRequired = true)]
public string Page
{
get
{
return (string)this["page"];
}
set
{
this["page"] = value;
}
}
[ConfigurationProperty("groups", IsRequired = true)]
public string Groups
{
get
{
return (string)this["groups"];
}
set
{
this["groups"] = value;
}
}
[ConfigurationProperty("display", IsRequired = true)]
public string Display
{
get
{
return (string)this["display"];
}
set
{
this["display"] = value;
}
}
[ConfigurationProperty("type", IsRequired = false)]
public string Type
{
get
{
return (string)this["type"];
}
set
{
this["type"] = value;
}
}
}
}
The code which is throwing error is this:
SiteModules siteModules = (SiteModules)ConfigurationManager.GetSection("SiteModules");
Exception not related to IsKey attribute. Look on overrided method GetelementKey. In given case it return Title.. which is not unique.
protected override Object GetElementKey(ConfigurationElement element)
{
return ((MainModule)element).Title;
}
I have a C# app that has a custom section of configuration info in the App.config file. At this time, I am able to successfully load the custom info via code. However, I'm trying to load that same configuration info from a database as well. In an attempt to do this, I took a string of XML from my App.config file that I know is working. That string of XML looks like this:
<departments>
<department id="1" name="Sporting Goods">
<products>
<product name="Basketball" price="9.99">
<add key="Color" value="Orange" />
<add key="Brand" value="[BrandName]" />
</product>
</products>
</department>
</departments>
I am trying to deserialize this XML into C# objects. I've defined these objects like this:
Departments.cs
public class Departments : ConfigurationSection
{
private Departments() { }
[ConfigurationProperty("", IsRequired = false, IsKey = false, IsDefaultCollection = true)]
public DepartmentItemCollection Items
{
get
{
var items = base[""] as DepartmentItemCollection;
return items;
}
set { base["items"] = value; }
}
public static Departments Deserialize(string xml)
{
Departments departments = null;
var serializer = new XmlSerializer(typeof(Departments));
using (var reader = new StringReader(xml))
{
departments = (Departments)(serializer.Deserialize(reader));
}
return departments;
}
}
[ConfigurationCollection(typeof(Department), CollectionType = ConfigurationElementCollectionType.BasicMapAlternate)]
public class DepartmentItemCollection : ConfigurationElementCollection
{
private const string ItemPropertyName = "department";
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMapAlternate; }
}
protected override string ElementName
{
get { return ItemPropertyName; }
}
protected override bool IsElementName(string elementName)
{
return (elementName == ItemPropertyName);
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Department)element).Name;
}
protected override ConfigurationElement CreateNewElement()
{
return new Department();
}
public override bool IsReadOnly()
{
return false;
}
}
Department.cs
public class Department : ConfigurationElement
{
public Department()
{ }
[ConfigurationProperty("id", IsRequired = false, IsKey = true)]
public int Id
{
get { return (int)(this["id"]); }
set { this["id"] = value; }
}
[ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
public string Name
{
get { return (string)(this["name"]); }
set { this["name"] = value; }
}
[ConfigurationProperty("products", IsRequired = false, IsKey = false, IsDefaultCollection = false)]
public ProductCollection Products
{
get { return ((ProductCollection)(base["products"])); }
set { base["products"] = value; }
}
}
DepartmentProducts.cs
[ConfigurationCollection(typeof(Product), AddItemName = "product", CollectionType = ConfigurationElementCollectionType.BasicMapAlternate)]
public class ProductCollection: ConfigurationElementCollection
{
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMapAlternate; }
}
protected override string ElementName
{
get { return string.Empty; }
}
protected override bool IsElementName(string elementName)
{
return (elementName == "product");
}
protected override object GetElementKey(ConfigurationElement element)
{
return element;
}
protected override ConfigurationElement CreateNewElement()
{
return new Product();
}
protected override ConfigurationElement CreateNewElement(string elementName)
{
var product = new Product();
return product;
}
public override bool IsReadOnly()
{
return false;
}
}
DepartmentProduct.cs
public class Product : ConfigurationElement
{
public Product()
{ }
[ConfigurationProperty("name", IsRequired = true, IsKey = true, DefaultValue = "")]
public string Name
{
get { return (string)(this["name"]); }
set { this["name"] = value; }
}
[ConfigurationProperty("price", IsRequired = false)]
public decimal Price
{
get { return (decimal)(this["price"]); }
set { price["name"] = value; }
}
[ConfigurationProperty("", IsRequired = false, IsKey = false, IsDefaultCollection = true)]
public KeyValueConfigurationCollection Items
{
get
{
var items = base[""] as KeyValueConfigurationCollection;
return items;
}
set { base["items"] = value; }
}
}
When I pass the XML shown above to the Departments.Deserialize method, I receive the following error:
InvalidOperationException: You must implement a default accessor on System.Configuration.ConfigurationLockCollection because it inherits from ICollection.
How do I deserialize the XML I shared into the C# objects shared?
I had a similar issue in the past. While I couldn't figure out how to deal with the InvalidOperationException, I managed to get it working by directly tagging the class as IXmlSerializable
[XmlRoot("departments")]
public class Departments : ConfigurationSection, IXmlSerializable
{
//Your code here..
public XmlSchema GetSchema()
{
return this.GetSchema();
}
public void ReadXml(XmlReader reader)
{
this.DeserializeElement(reader, false);
}
public void WriteXml(XmlWriter writer)
{
this.SerializeElement(writer, false);
}
}
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;
}
}
}
}
}
}
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; }
}
}
I have the following bits in App.config for a .NET 3.5 Windows Service:
<configSections>
<section name="ConfigurationServiceSection" type="SomeApp.Framework.Configuration.ConfigurationServiceSection, SomeApp.Framework"/>
</configSections>
<ConfigurationServiceSection configSource="ConfigSections\configurationServiceSection.config" />
I've got this in configurationServiceSection.config:
<ConfigurationServiceSection>
<ConfigurationServices>
<ConfigurationService name="LocalConfig" host="localhost" port="40001" location="LON"/>
</ConfigurationServices>
</ConfigurationServiceSection>
And here's the code:
using System.Configuration;
namespace SomeApp.Framework.Configuration
{
public sealed class ConfigurationServiceSection : ConfigurationSection
{
[ConfigurationProperty("ConfigurationServices", IsDefaultCollection = true, IsRequired = true)]
[ConfigurationCollection(typeof(ConfigurationServices))]
public ConfigurationServices ConfigurationServices
{
get
{
return (ConfigurationServices)base["ConfigurationServices"];
}
}
}
public sealed class ConfigurationServices : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new ConfigurationService();
}
protected override object GetElementKey(ConfigurationElement element)
{
ConfigurationService configService = (ConfigurationService) element;
return configService.Name;
}
}
public sealed class ConfigurationService : ConfigurationElement
{
/// <summary>
/// name
/// </summary>
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}
/// <summary>
/// host
/// </summary>
[ConfigurationProperty("host", IsKey = false, IsRequired = true)]
public string Host
{
get { return (string)this["host"]; }
set { this["host"] = value; }
}
/// <summary>
/// port
/// </summary>
[ConfigurationProperty("port", IsKey = false, IsRequired = true)]
public string Port
{
get { return (string)this["port"]; }
set { this["port"] = value; }
}
/// <summary>
/// location
/// </summary>
[ConfigurationProperty("location", IsKey = false, IsRequired = true)]
public string Location
{
get { return (string)this["location"]; }
set { this["location"] = value; }
}
}
}
When I try to access the config with the following:
var configurationServiceSection = (ConfigurationServiceSection)configuration.GetSection("ConfigurationServiceSection");
I get this exception:
Unrecognized element 'ConfigurationService'. (C:\Code\branches\ConfigurationService\SomeApp\Src\ConfigService\SomeApp.ConfigService.WindowsService\bin\Debug\ConfigSections\configurationServiceSection.config line 3)
Everything looks in order to me?
Any ideas please? Thanks.
Ok got to the bottom of this:
I added 'AddItemName' to the ConfigurationServiceSection class, as per below:
public sealed class ConfigurationServiceSection : ConfigurationSection
{
[ConfigurationProperty("ConfigurationServices", IsDefaultCollection = true, IsRequired = true)]
[ConfigurationCollection(typeof(ConfigurationServices), AddItemName = "ConfigurationService")]
public ConfigurationServices ConfigurationServices
{
get
{
return (ConfigurationServices)base["ConfigurationServices"];
}
}
}
Another alternative was to override the CollectionType and ElementName properties, as per below:
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override string ElementName
{
get { return "ConfigurationService"; }
}