I have implemented custom section in web.config and want to save data there, in runtime debug when you check it contains all values that you put there and save without any exception. But web.config file didn't get updated at all.
I have following custom section in web.config
public class PrintersSection : ConfigurationSection
{
[ConfigurationProperty("PrintForm", Options = ConfigurationPropertyOptions.IsRequired)]
public PrintFormElement PrintForm
{
get
{
return (PrintFormElement)this["PrintForm"];
}
set { this["PrintForm"] = value; }
}
[ConfigurationProperty("Printers", Options = ConfigurationPropertyOptions.IsRequired)]
public PrintersCollection Printers
{
get
{
return (PrintersCollection)this["Printers"];
}
set { this["Printers"] = value; }
}
public override bool IsReadOnly()
{
return false;
}
}
public class PrintFormElement : ConfigurationElement
{
[ConfigurationProperty("xmlPath")]
public string XmlPath
{
get
{
return (string)base["xmlPath"];
}
set { base["xmlPath"] = value; }
}
[ConfigurationProperty("formName")]
public string FormName
{
get
{
return (string)base["formName"];
}
set { base["formName"] = value; }
}
[ConfigurationProperty("sdateFormat")]
public string SDateFormat
{
get
{
return (string)base["sdateFormat"];
}
set { base["sdateFormat"] = value; }
}
[ConfigurationProperty("createOnTechpadMarkAsComplete")]
public bool CreateOnTechpadMarkAsComplete
{
get
{
return (bool)base["createOnTechpadMarkAsComplete"];
}
set { base["createOnTechpadMarkAsComplete"] = value; }
}
[ConfigurationProperty("createOnSurveySubmit")]
public bool CreateOnSurveySubmit
{
get
{
return (bool)base["createOnSurveySubmit"];
}
set { base["createOnSurveySubmit"] = value; }
}
public override bool IsReadOnly()
{
return false;
}
}
[ConfigurationCollection(typeof(PrinterElement), AddItemName = "printer", CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
public class PrintersCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new PrinterElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
if (element == null)
throw new ArgumentNullException("element");
return ((PrinterElement)element).Location;
}
[ConfigurationProperty("default", IsRequired = false)]
public string Default
{
get
{
return (string)base["default"];
}
set { base["default"] = value; }
}
public new PrinterElement this[string location]
{
get { return base.BaseGet(location) as PrinterElement; }
}
public void Add(PrinterElement element)
{
base.BaseAdd(element);
}
public void Clear()
{
base.BaseClear();
}
public override bool IsReadOnly()
{
return false;
}
}
public class PrinterElement : ConfigurationElement
{
[ConfigurationProperty("location", IsRequired = true, IsKey = true)]
public string Location
{
get
{
return (string)base["location"];
}
set { base["location"] = value; }
}
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return (string)base["name"];
}
set { base["name"] = value; }
}
public override bool IsReadOnly()
{
return false;
}
}
Here how it looks in web.config:
<printers>
<PrintForm xmlPath="H:\Temp\print3.txt" formName="test-form"
sdateFormat="MM-dd-yyyy" createOnTechpadMarkAsComplete="true"
createOnSurveySubmit="true" />
<Printers default="PrinterA">
<clear />
<printer location="1" name="PrinterA" />
<printer location="2" name="PrinterB" />
</Printers>
</printers>
This is how I editing it:
webConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
var printXmlConfig = (PrintersSection)ConfigurationManager.GetSection("printers");
printXmlConfig.PrintForm.XmlPath = model.PrintXMLPath;
printXmlConfig.PrintForm.FormName = model.PrintXMLFormName;
printXmlConfig.Printers.Default = model.PrintXMLPrinterName;
printXmlConfig.PrintForm.SDateFormat = model.PrintXMLSDateFormat;
printXmlConfig.PrintForm.CreateOnTechpadMarkAsComplete = model.PrintXMLCreateOnTechpadMarkAsComplete;
printXmlConfig.PrintForm.CreateOnSurveySubmit = model.PrintXMLCreateOnSurveySubmit;
printXmlConfig.Printers.Clear();
model.PrinterPerLocation.ForEach(p => printXmlConfig.Printers.Add(new PrinterElement { Location = p.Key, Name = p.Value}));
webConfig.Save();
But nothing updates in web.config, what I am doing wrong here?
Try
printXmlConfig.SectionInformation.ForceSave = true;
or
webConfig.SectionInformation.ForceSave = true;
before
webConfig.Save(ConfigurationSaveMode.Full);
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'm using ServerManager (Microsoft.Web.Administration.dll) to create an Application to manage my web servers, All of my server are running IIS 7 and above. Majority of the site is complete, i can manage servers, sites, FTP, SSL etc.
Here is my issue,
I am able to create virtual directories and applications, but having an issue with listing them separately when viewing the site information as you can do in IIS. I am able to list the all together as Virtual Directories by just getting item.VirtualDirectories[0].PhysicalPath but would like to show Applications in one column and basic virtual directories in the second column. I'm sure i need to be looking for if root application path is siteid, or if it has an AppPool somehow but having a hard time figuring how. Any help would be appreciated.
My Code:
SiteVirtualDirectory.cs
private string anonymousUsername;
private string anonymousUserPassword;
private string contentPath;
private bool enableWritePermissions;
private bool enableParentPaths;
private bool enableDirectoryBrowsing;
private bool enableAnonymousAccess;
private bool enableWindowsAuthentication;
private bool enableBasicAuthentication;
private bool enableDynamicCompression;
private bool enableStaticCompression;
private string defaultDocs;
private string httpRedirect;
private HttpError[] httpErrors;
private HttpErrorsMode errorMode;
private HttpErrorsExistingResponse existingResponse;
private MimeMap[] mimeMaps;
private HttpHeader[] httpHeaders;
private bool aspInstalled;
private string aspNetInstalled;
private string phpInstalled;
private bool perlInstalled;
private bool pythonInstalled;
private bool coldfusionInstalled;
private bool cgiBinInstalled;
private string applicationPool;
private bool dedicatedApplicationPool;
private string parentSiteName;
private bool redirectExactUrl;
private bool redirectDirectoryBelow;
private bool redirectPermanent;
private bool sharePointInstalled;
private bool iis7;
private string consoleUrl;
private string php5VersionsInstalled;
public string AnonymousUsername
{
get { return anonymousUsername; }
set { anonymousUsername = value; }
}
public string AnonymousUserPassword
{
get { return anonymousUserPassword; }
set { anonymousUserPassword = value; }
}
public string ContentPath
{
get { return contentPath; }
set { contentPath = value; }
}
public string HttpRedirect
{
get { return httpRedirect; }
set { httpRedirect = value; }
}
public string DefaultDocs
{
get { return defaultDocs; }
set { defaultDocs = value; }
}
public MimeMap[] MimeMaps
{
get { return mimeMaps; }
set { mimeMaps = value; }
}
public HttpError[] HttpErrors
{
get { return httpErrors; }
set { httpErrors = value; }
}
public HttpErrorsMode ErrorMode
{
get { return errorMode; }
set { errorMode = value; }
}
public HttpErrorsExistingResponse ExistingResponse
{
get { return existingResponse; }
set { existingResponse = value; }
}
public string ApplicationPool
{
get { return this.applicationPool; }
set { this.applicationPool = value; }
}
public bool EnableParentPaths
{
get { return this.enableParentPaths; }
set { this.enableParentPaths = value; }
}
public HttpHeader[] HttpHeaders
{
get { return this.httpHeaders; }
set { this.httpHeaders = value; }
}
public bool EnableWritePermissions
{
get { return this.enableWritePermissions; }
set { this.enableWritePermissions = value; }
}
public bool EnableDirectoryBrowsing
{
get { return this.enableDirectoryBrowsing; }
set { this.enableDirectoryBrowsing = value; }
}
public bool EnableAnonymousAccess
{
get { return this.enableAnonymousAccess; }
set { this.enableAnonymousAccess = value; }
}
public bool EnableWindowsAuthentication
{
get { return this.enableWindowsAuthentication; }
set { this.enableWindowsAuthentication = value; }
}
public bool EnableBasicAuthentication
{
get { return this.enableBasicAuthentication; }
set { this.enableBasicAuthentication = value; }
}
public bool EnableDynamicCompression
{
get { return this.enableDynamicCompression; }
set { this.enableDynamicCompression = value; }
}
public bool EnableStaticCompression
{
get { return this.enableStaticCompression; }
set { this.enableStaticCompression = value; }
}
public bool AspInstalled
{
get { return this.aspInstalled; }
set { this.aspInstalled = value; }
}
public string AspNetInstalled
{
get { return this.aspNetInstalled; }
set { this.aspNetInstalled = value; }
}
public string PhpInstalled
{
get { return this.phpInstalled; }
set { this.phpInstalled = value; }
}
public bool PerlInstalled
{
get { return this.perlInstalled; }
set { this.perlInstalled = value; }
}
public bool PythonInstalled
{
get { return this.pythonInstalled; }
set { this.pythonInstalled = value; }
}
public bool ColdFusionInstalled
{
get { return this.coldfusionInstalled; }
set { this.coldfusionInstalled = value; }
}
public bool DedicatedApplicationPool
{
get { return this.dedicatedApplicationPool; }
set { this.dedicatedApplicationPool = value; }
}
public string ParentSiteName
{
get { return this.parentSiteName; }
set { this.parentSiteName = value; }
}
public bool RedirectExactUrl
{
get { return this.redirectExactUrl; }
set { this.redirectExactUrl = value; }
}
public bool RedirectDirectoryBelow
{
get { return this.redirectDirectoryBelow; }
set { this.redirectDirectoryBelow = value; }
}
public bool RedirectPermanent
{
get { return this.redirectPermanent; }
set { this.redirectPermanent = value; }
}
public bool CgiBinInstalled
{
get { return this.cgiBinInstalled; }
set { this.cgiBinInstalled = value; }
}
public bool SharePointInstalled
{
get { return this.sharePointInstalled; }
set { this.sharePointInstalled = value; }
}
public bool IIs7
{
get { return this.iis7; }
set { this.iis7 = value; }
}
public string ConsoleUrl
{
get { return consoleUrl; }
set { consoleUrl = value; }
}
public string Php5VersionsInstalled
{
get { return php5VersionsInstalled; }
set { php5VersionsInstalled = value; }
}
[XmlIgnore]
public string VirtualPath
{
get
{
// virtual path is rooted
if (String.IsNullOrEmpty(ParentSiteName))
return "/"; //
else if (!Name.StartsWith("/"))
return "/" + Name;
//
return Name;
}
}
[XmlIgnore]
public string FullQualifiedPath
{
get
{
if (String.IsNullOrEmpty(ParentSiteName))
return Name;
else if (Name.StartsWith("/"))
return ParentSiteName + Name;
else
return ParentSiteName + "/" + Name;
}
}
Get Virtual Directories:
public class GetVirtualDirectories(ServerManager iismanager, string siteId)
{
if (!SiteExists(iismanager, siteId))
return new SiteVirtualDirectory[] { };
var vdirs = new List<SiteVirtualDirectory>();
var iisObject = iismanager.Sites[siteId];
//
foreach (var item in iisObject.Applications)
{
// do not list root Virtual Directory
if (item.Path == "/")
continue;
//
vdirs.Add(new SiteVirtualDirectory
{
Name = ConfigurationUtility.GetNonQualifiedVirtualPath(item.Path),
ContentPath = item.VirtualDirectories[0].PhysicalPath
});
}
//
return vdirs.ToArray();
}
I'm creating a custom configuration section but I keep getting a Attribute Not Recognized error when trying to get the section.
I'm pretty sure it's some dumb typo - hopefully someone here can spot it.
Code:
<configSections>
<section name="ClientFilterSettings" type="ESPDB.Config.ClientFilterSettings, ESPDB"/>
</configSections>
<ClientFilterSettings>
<AllowedIPs>
<IPAddress IP="255.255.255.255"/>
</AllowedIPs>
</ClientFilterSettings>
Section:
namespace ESPDB.Config
{
public class ClientFilterSettings : ConfigurationSection
{
private static ClientFilterSettings _settings =
ConfigurationManager.GetSection(typeof(ClientFilterSettings).Name) as ClientFilterSettings
/*?? new ClientFilterSettings()*/;
private const string _allowedIPs = "AllowedIPs";
public static ClientFilterSettings Settings
{
get { return _settings; }
}
[ConfigurationProperty(_allowedIPs, IsRequired = true)]
[ConfigurationCollection(typeof(IPAddressCollection))]
public IPAddressCollection AllowedIPs
{
get { return (IPAddressCollection)this[_allowedIPs]; }
set { this[_allowedIPs] = value; }
}
}
}
Collection:
namespace ESPDB.Config
{
public class IPAddressCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new IPAddressCollection();
}
protected override object GetElementKey(ConfigurationElement element)
{
return (element as IPAddressElement).IP;
}
protected override string ElementName
{
get { return "IPAddress"; }
}
public IPAddressElement this[int index]
{
get
{
return base.BaseGet(index) as IPAddressElement;
}
set
{
if (base.BaseGet(index) != null)
{
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}
public new IPAddressElement this[string responseString]
{
get { return (IPAddressElement)BaseGet(responseString); }
set
{
if (BaseGet(responseString) != null)
{
BaseRemoveAt(BaseIndexOf(BaseGet(responseString)));
}
BaseAdd(value);
}
}
}
}
Element
namespace ESPDB.Config
{
public class IPAddressElement : ConfigurationElement
{
private const string _ip = "IP";
[ConfigurationProperty(_ip, IsKey = true, IsRequired = true)]
public string IP
{
get { return this[_ip] as string; }
set { this[_ip] = value; }
}
}
}
There are multiple problems in your code.
1). You are recursively creating objects of ClientFilterSettings. Remove the following code, its not required.
private static ClientFilterSettings _settings =
ConfigurationManager.GetSection(typeof(ClientFilterSettings).Name) as ClientFilterSettings /*?? new ClientFilterSettings()*/;
public static ClientFilterSettings Settings
{
get { return _settings; }
}
2). Change the attribute from
[ConfigurationCollection(typeof(IPAddressCollection))]
TO
[ConfigurationCollection(typeof(IPAddressElement), AddItemName = "IPAddress", CollectionType = ConfigurationElementCollectionType.BasicMap)]
3). You are creating collection object within a collection. Modify the code below
return new IPAddressCollection();
WITH
return new IPAddressElement();
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
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);
}
}