Access ConfigurationSection from ConfigurationElement - c#

I have a configuration class that maps web.config, something like that:
public class SiteConfigurationSection : ConfigurationSection
{
[ConfigurationProperty("defaultConnectionStringName", DefaultValue = "LocalSqlServer")]
public string DefaultConnectionStringName
{
get { return (string)base["defaultConnectionStringName"]; }
set { base["defaultConnectionStringName"] = value; }
}
[ConfigurationProperty("Module", IsRequired = true)]
public ModuleElement Module
{
get { return (ModuleElement)base["Module"]; }
}
}
public class ModuleElement : ConfigurationElement
{
[ConfigurationProperty("connectionStringName")]
public string ConnectionStringName
{
get { return (string)base["connectionStringName"]; }
set { base["connectionStringName"] = value; }
}
public string ConnectionString
{
get
{
string str;
if (string.IsNullOrEmpty(this.ConnectionStringName))
{
str =//GET THE DefaultConnectionStringName from SiteConfigurationSection;
}
else
str = this.ConnectionStringName;
return WebConfigurationManager.ConnectionStrings[str].ConnectionString;
}
}
}
Meaning if connection string name value is missing in Module section in web.config file, the value should be read from configurationsection.
How to do that?

This would depend on the name of your section's tag.
var cs =
((SiteConfigurationSection)WebConfigurationManager
.GetSection("mySectionTag")).DefaultConnectionString;

Related

Entry has already been added error even though IsKey is false

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;
}

Custom web.config section not saving

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);

Unrecognized attribute custom configuration (again)

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();

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;

Categories