My web config is as follows:
<appSettings>
<add key="One" value="1" xdt:Transform="Insert"/>
</appSettings>
If I need to access the value 1, I can write the below code:
ConfigurationManager.AppSettings("One");
But if the web config is like,
<countryAppSettings>
<add key="Two" value="2" xdt:Transform="Insert"/>
</countryAppSettings>
can I access the value in the following form, using a helper class for ConfigurationManager class
ConfigurationManager.CountryAppSettings("Two");
Is this possible in c#?
Yes you can do this, although you do also need to include a custom config section in your configuration file. There's an MSDN article here describing how to do it.
So you'll need to add in your custom configuration section first:
<configuration>
<configSections>
<sectionGroup name="countrySettings">
<section name="countrySetting" type="Custom.CountrySettingSection" allowLocation="true" allowDefinition="Everywhere" />
</sectionGroup>
</configSections>
</configuration>
You'd then typically define your settings more like this, which is great if you've got a really rich object:
<countrySetting customKey="2">
<richerObject>2</richerObject>
</countrySetting>
You'd then need a backing object constructed like so:
namespace Custom
{
public class CountrySettingSection : ConfigurationSection
{
// Create a "customKey" attribute.
[ConfigurationProperty("customKey", DefaultValue = "0", IsRequired = false)]
public int CustomKey
{
get
{
return (int)this["customKey"];
}
set
{
this["customKey"] = value;
}
}
}
You can't create that way. maybe should visit this link
https://msdn.microsoft.com/en-us/library/bb383977.aspx
ConfigurationManager.AppSetting is property ,no method. This
property type is NameValueCollection you can use like this
ConfigurationManager.AppSettings["One"] or
ConfigurationManager.AppSettings.GetValues("One")
You can customize your web.config
https://msdn.microsoft.com/en-us/library/2tw134k3.aspx
Related
I've got a web api where I've added a custom section into the web.config as per this link: https://msdn.microsoft.com/en-us/library/2tw134k3.aspx. My web.config looks as follows:
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please
visit https://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<configSections>
<sectionGroup name="productGroup">
<section
name="product"
type="myProject.Stuff.Api.ProductSection"
allowLocation="true"
allowDefinition="Everywhere"
/>
</sectionGroup>
</configSections>
<appSettings>
<!-- various app settings -->
</appSettings>
<productGroup>
<product name="my name" id="1" />
<product name="my name 2" id="2" />
</productGroup>
<!-- other standard elements -->
</configuration>
I added in the configSections and the productGroup. I then define a c# class as ProductSection as follows:
using System.Configuration;
namespace myProject.Stuff.Api
{
public class ProductSection : ConfigurationSection
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("id", IsRequired = true)]
public int Id
{
get
{
return (int)this["id"];
}
set
{
this["id"] = value;
}
}
}
}
I've copied the 2 sections across to my app.config in my test project, but when I now try and debug a test I get the failed to initialize error. When I comment out the productGroup section it then stops complaining. What have I done wrong?
UPDATE
As a side note I ended up structuring it a little more simply. As my 'product' sections only needed a name and id they lent themselves to key value pairs as per appSettings. So I created a section like this:
<configSections>
<section name="productGroup"
type="System..Configuration.NameValueSectionHandler"
allowLocation="true"
allowDefinition="Everywhere"/>
</configSections>
Note that I changed the type. My productGroup then looked like this:
<productGroup>
<add key="product1" value="1" />
<add key="product2" value="2" />
</productGroup>
I then could remove the ProductSection class altogether and just reference my group of products like this:
var products = ConfigurationManager.GetSection("productGroup") as NameValueCollection;
if (products.AllKeys.Contains(myProduct))
{
var myValue = products[myProduct];
}
I notice 2 things
A configuration section can only appear 1 time within a configuration file.
The full initialization exception shows:
System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize --->
System.Configuration.ConfigurationErrorsException: Sections must only appear once per config file.
This means you can only have 1 product section:
<productGroup>
<product name="my name" id="1" />
</productGroup>
If you need multiple, you need to declare multiple sections with unique section names:
<configuration>
<sectionGroup name="productGroup">
<section name="product" type="myProject.Stuff.Api.ProductSection" />
<section name="product2" type="myProject.Stuff.Api.ProductSection" />
</sectionGroup>
<!-- Other configuration elements -->
<productGroup>
<product name="my name" id="1" />
<product2 name="my name 2" id="2" />
</productGroup>
</configuration>
It is a best practice to declare the section in app/web.config with its fully qualified assemblyname,
which includes the name of the assembly (without file extension).
This is a must if the class/section is defined in an external assembly; here ProductionSection is defined in an assembly other than the one of the main unittest.
Declare the section as below in the App.config file of your unittest project.
(Replace NameOfTheAssemblyContainingTheProductSectionClass with the name of your assembly.)
<section
name="product"
type="myProject.Stuff.Api.ProductSection, NameOfTheAssemblyContainingTheProductSectionClass"
/>
I have a Configuration-File that I read with the ConfigurationManager. There are some Sections that I defined by myself.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="applicationWideSettingsSection" type="MyTestApp.ApplicationSettings.ApplicationWideSettingsSection, MyTestAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<applicationWideSettingsSection>
<pathToSomeFile value="C:\Users\..." />
</applicationWideSettingsSection>
</configuration>
There are new requirements: now I have to store another value in the applicationWideSettingsSection like this:
<applicationWideSettingsSection>
<pathToSomeFile value="C:\Users\..." />
<pathToSomeOtherFile value="C:\Programs\..." />
</applicationWideSettingsSection>
So I change my definition of the applicationWideSettingsSection. If I now run the application with an old config-File it throws an exception on this line:
var configSection = _config.GetSection("applicationWideSettingsSection");
because there is only the pathToSomeFile-Setting and the other one is missing.
Is there a way to manually add another (default value) to this section?
How would you deal with this??
Thanks in advance, Joerg
Because I didn't want to change my design away from my custom Setting-Types I found a different way:
I set the IsRequired to false so no exception is thrown when the setting is missing. If it's missing I set it to some value from code.
In a different approach I wanted to override some of the Configuration-Section methods but did not get it to work...
now I have to store another value in the applicationWideSettingsSection
Instead of your custom type ApplicationWideSettingsSection you can use a key-value pairs, so
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="applicationWideSettingsSection"
type="System.Configuration.NameValueSectionHandler" />
</configSections>
<applicationWideSettingsSection>
<pathToSomeFile value="C:\Users\..." />
</applicationWideSettingsSection>
</configuration>
This will store 1 or many parameters and allow you to enumerate on the inner parameters. You can also try DictionarySectionHandler. I found sample code in this post.
In the root folder of my ASP.NET MVC 5 I have two config files. one is the default web.config file and the second one is department.config.
The content of the department.config file is:
<department>
<add key="dept1" value="xyz.uvw.rst" />
<add key="dept2" value="abc.def.ghi" />
<department>
How to read the department.config file ?
I want to get a collection of values under <department> in this config file.
Edit: Web.config has <department configSource="reports.config" />
so, how to read the configSource file in asp.net mvc ?
Edit:
<configuration>
<configSections>
<section name="departments"
type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
restartOnExternalChanges="false"
requirePermission="false" />
In your web.config, you can specify other files that the built-in ConfigurationManager can easily access. For example, we decided that we wanted to separate connection strings and application setting into separate files. You can do this by putting this in your web.config:
<appSettings configSource="appsettings.config" />
Then you can access these values in the 'regular' way
ConfigurationManager.AppSettings["KeyHere"]
Same thing with connection strings...
Why not use the appSettings section in your web.config? These are easy to read using ConfigurationManager object.
In your web.config, find the appSettings section:
<appSettings>
<add key="dept1" value="xyz.uvw.rst"/>
Then in your class where you want to read it, import the correct namespace:
using System.Configuration;
And then read the value easily, like so:
var dept1 = ConfigurationManager.AppSettings.Get("dept1");
If you have to have it in a separate config, you might consider creating a class for it, I'll post up an example of that shortly.
edit1: here is a quick example of how to do your own custom config
first, define the config class:
using System;
using System.Configuration;
namespace WebApplication2
{
public class MyConfig : ConfigurationSection
{
private static readonly MyConfig ConfigSection = ConfigurationManager.GetSection("MyConfig") as MyConfig;
public static MyConfig Settings
{
get
{
return ConfigSection;
}
}
[ConfigurationProperty("Dept1", IsRequired = true)]
public string Dept1
{
get
{
return (string)this["Dept1"];
}
set
{
this["Dept1"] = value;
}
}
[ConfigurationProperty("Dept2", IsRequired = true, DefaultValue = "abc.def.ghi")]
public string Dept2
{
get
{
return (string)this["Dept2"];
}
set
{
this["Dept2"] = value;
}
}
// added as example of different types
[ConfigurationProperty("CheckDate", IsRequired = false, DefaultValue = "7/3/2014 1:00:00 PM")]
public DateTime CheckDate
{
get
{
return (DateTime)this["CheckDate"];
}
set
{
this["CheckDate"] = value;
}
}
}
}
Then, set it up in your web.config file:
<configuration>
<configSections>
<section name="MyConfig" type="WebApplication2.MyConfig, WebApplication2" />
</configSections>
<MyConfig Dept1="xyz.uvw.rst" Dept2="abc.def.ghi" />
...
</configuration>
And then you can call it very easily, along with strong-typing and support for many types:
var dept1 = MyConfig.Settings.Dept1;
var dept2 = MyConfig.Settings.Dept2;
// strongly-typed
DateTime chkDate = MyConfig.Settings.CheckDate;
That's how I would do it. Use the built-in stuff and create a class for it. Easy to do config transforms with, easy to read, and easy to use.
This is an old question but in the event someone needs to know... First geekzsters answer lays out how to write a config class. Then you specify a custom Config Section and give it a configSource in a separate file.
<configuration>
<configSections>
<section name="myCustomSection" type="MyNamespace.MyCustomType" requirePermission="false" />
</configSections>
</configuration>
<myCustomSection configSource="myConfigDir\myFile.config" />
Then in your custom config file you write a normal xml config
<?xml version="1.0" encoding="utf-8"?>
<myCustomSection>
<myCustomType>
<add name="pro1" value="abc" />
<add name="prop2" value="cde" />
<add name="prop3" value="efg" />
</myCustomType>
</myCustomSection>
The simplest way to read configuration File other then Web config is to define file you want to read as follows:
webConfig
<appSettings file="TestFile.config">
<add key="webpages:Version" value="3.0.0.0"/>
<add key="webpages:Enabled" value="false"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
TestFile.Config
<appSettings>
<add key="test" value="testData"/>
</appSettings>
Above we define the file we want to read configuration from in Webconfig. thus using ConfigurationManager.AppSettings['test'] you can read the value from your newly created custom config file.
I've been following this tutorial on msdn which loads a custom configSection. http://msdn.microsoft.com/en-us/library/system.configuration.configurationcollectionattribute.aspx I'm doing this in asp.net and I keep getting an error on
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None) as Configuration;
so i removed that and just used
UrlsSection myUrlsSection =
ConfigurationManager.GetSection("MyUrls") as UrlsSection;
Could someone copy and past the code from msdn and make a project in asp.net and test the code and see if they get same error or see if myUrlsSection = null and if you don't get a problem could you share what you did to make it work
This is what I tried and it works nice.
UrlsSection myUrlsSection =
ConfigurationManager.GetSection("MyUrls") as UrlsSection;
My UrlsSection class
namespace MyProject
{
public class UrlsSection : ConfigurationSection
{
}
}
And my config entry.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MyUrls" type="MyProject.UrlsSection, MyProject" />
</configSections>
<MyUrls />
</configuration>
I recently started building a console version of a web application. I copied my custom sections from my web.config. to my app.config. When I go to get config information i get this error:
An error occurred creating the configuration section handler for x/y: Could not load type 'x' from assembly 'System.Configuration
The line that it is not liking is:
return ConfigurationManager.GetSection("X/Y") as Z;
Anyone run into something like this?
I was able to add
<add key="IsReadable" value="0"/>
in the appSettings and read it.
Addition:
I do actually have this defined about the custom section:
<configSections>
<sectionGroup name="x">
<section name="y" type="zzzzz"/>
</sectionGroup>
</configSections>
it sounds like your config-section handler is not defined
<configSection>
<section
name="YOUR_CLASS_NAME_HERE"
type="YOUR.NAMESPACE.CLASSNAME, YOUR.NAMESPACE, Version=1.1.0.0, Culture=neutral, PublicKeyToken=PUBLIC_TOKEN_ID_FROM_ASSEMBLY"
allowLocation="true"
allowDefinition="Everywhere"
/>
</configSection>
I had this identical issue recently. I created a custom sectiongroup for a web application(ran just fine), but when I ported this layer to a console app, the sectiongroup was failing.
You were correct in your question regarding how much of the "type" is required in your section definition. I've modified your configuration section with an example below:
<configSection>
<section
name="yourClassName"
type="your.namespace.className, your.assembly"
allowLocation="true"
allowDefinition="Everywhere" />
</configSection>
You'll notice, the type now has class name followed by assembly name. This is required for interaction outside of a web environment.
NOTE: Assembly name does not necessarily equal your namespace(for a given section).
If you want a custom config handler you have to define the class and reference it as shown by Steven Lowe. You can inherit from predefined handlers, or you can just use the value/key pair that is offered in appSetting section as you noted.
At the top of your file you require to have configSection tag with inside the section.
You can have sectionGroup too. Example:
<configuration>
<configSections>
<sectionGroup name="x">
<section name="y" type="a, b"/>
</sectionGroup>
<configSections>
</configuration>
This class works as a general custom configuration section handler for any type...
public class XmlConfigurator : IConfigurationSectionHandler
{
public object Create(object parent, object configContext, XmlNode section)
{
if (section == null) return null;
Type sectionType = Type.GetType((string)(section.CreateNavigator()).Evaluate("string(#configType)"));
XmlSerializer xs = new XmlSerializer(sectionType);
return xs.Deserialize(new XmlNodeReader(section));
}
}
In your app.config, add
<section name="NameofConfigSection" type="NameSpace.XmlConfigurator, NameSpace.Assembly"/>
And in the configuration section element, add an attribute to specify the type you want the root element deserialized into..
<?xml version="1.0" encoding="utf-8" ?>
<NameofConfigSection configType="NameSpace.NameofTypeToDeserializeInto, Namespace.Assembly" >
...
</NameofConfigSection>