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>
Related
I am trying to read in my own custom values from the App.config, but I keep getting an error saying the following:
Could not load type 'StockCSV.CordnersConfiguration' from assembly 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Any help would be great, thanks in advance!
Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="CordnerConfigurationSection">
<section
name="cordnerConfig"
type="StockCSV.CordnersConfiguration.CordnerConfigurationSection, StockCSV.CordnersConfiguration"
allowLocation="false"
allowDefinition="Everywhere" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<CordnerConfigurationSection>
<cordnerConfig Location="C:\Users\Conor\Desktop\Cordners Data Dump\stocknew.csv"></cordnerConfig>
</CordnerConfigurationSection>
</configuration>
Code
namespace StockCSV.CordnersConfiguration
{
public class CordnerConfigurationSection : ConfigurationSection
{
private static CordnerConfigurationSection cordnerConfig = (CordnerConfigurationSection)System.Configuration.ConfigurationManager.GetSection("CordnerConfigurationSection/cordnerConfig");
private const string OutputPathProviderName = "outputPath";
public static CordnerConfigurationSection CordnerConfig => cordnerConfig;
[ConfigurationProperty(OutputPathProviderName)]
public OutputConfigurationElement OutputLocation
{
get => (OutputConfigurationElement) this[OutputPathProviderName];
set => this[OutputPathProviderName] = value;
}
}
}
Custom config sections must follow the below pattern, as per documentation
<section
name="sectionname"
type="configuration section handler class, assembly file name, version, culture, public key token"
/>
In your case, the config type may be set incorrectly. Check spelling are correct, particularly the name of the assembly is correct.
I believe, your type should be
type="StockCSV.CordnersConfiguration.CordnerConfigurationSection, StockCSV"
Let me know if that solves it or not.
I have to get string inside Setting-> Value in C#. How to reach there through code and fetch that value from App.config file. Please help me. Thank you.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="MyApplication.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<applicationSettings>
<MyApplication.Properties.Settings>
**<setting name="ConnectionString" serializeAs="String">
<value>server=127.0.0.1;uid=root;pwd=root;database=MyApplication_db;</
</setting>**
</VASI_Application.Properties.Settings>
</applicationSettings>
</configuration>
You can use the following code:
var section = (ClientSettingsSection)ConfigurationManager.GetSection("applicationSettings/MyApplication.Properties.Settings");
var settingElement = section.Settings.Get("ConnectionString");
var settingValue = settingElement.Value.ValueXml.InnerText;
// settingValue equals "server=127.0.0.1;uid=root;pwd=root;database=MyApplication_db;"
First, you retrieve the ClientSettingsSection section. The name of the section is a combination of the name of the "applicationSettings" section and its inner "MyApplication.Properties.Settings" section. Then, you retrieve the actual settings by calling Settings.Get("ConnectionString") on the returned ClientSettingsSection instance. Finally, you can use the Value.ValueXml.InnerText property of the returned setting to get to the actual value.
By the way, you have two small errors in your XML file:
The <MyApplication.Properties.Settings> element in incorrectly closed with </VASI_Application.Properties.Settings>
The <value> element is not correctly closed with </value>
Don't you have the property ConnectionString?
As documented here, usually you can access it in this way:
var setting = Properties.Settings.Default.ConnectionString;
By the way, your application tag starts with MyApplication.Properties.Settings but ends with VASI_Application.Properties.Settings
If you do actually want to go ahead with a custom config file section like in your example then you will need to follow this Microsoft guide for creating custom configuration sections.
https://msdn.microsoft.com/en-us/library/2tw134k3.aspx
If you get stuck following this guide then raise another question.
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.
My App.config file is markuped as:
<configuration>
<configSections>
<section name="Custom" type="…" />
</configSections>
<Custom>
...
</Custom>
<Ignored>
...
</Ignored>
</configuration>
So, I have an configuration file, where:
one section ("Custom") is handled by API and I have written ConfigurationSection inheritor for it
second section ("Ignored") I will parse by myself, because Configuration API doesnt let me solve my task.
When I run program, exception occurs "Unrecognized configuration section 'Ignored'".
Do I have possibility to tell ConfigurationManager to ignore this section "Ignored"?
You can add the following to your <configSections> element:
<section name="Ignored" type="System.Configuration.IgnoreSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
I want to select SMS section block according to tip attribute of SMS xml.
Currently: ConfigurationManager.GetSection("Logger/Sms") works but is there any way to get section like ConfigurationManager.GetSection("Logger/Sms[#tip='VF']")?
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="Logger">
<section name="Sms" type="caSectionTest.LogHandler, caSectionTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</sectionGroup>
</configSections>
<Logger>
<Sms tip="Clickatell">
<icerik>Soğuk zincir uygulamasından gönderilen sms</icerik>
<telNo>9053123123123</telNo>
<api>3363050</api>
<user>pkUser</user>
<pass>passhm</pass>
</Sms>
<Sms tip="Vodafone">
<icerik>write something into sms</icerik>
<telNo>905123123123</telNo>
<originator>336123</originator>
<user>ctUser</user>
<pass>9Mdfpass</pass>
</Sms>
</Logger>
</configuration>
You've probably long since moved on, but I created an XPath lookup for xml XElement recently available here: https://github.com/ChuckSavage/XmlLib/ If you want to use jsobo's comment to get the information you want.
You would use it like:
XElement root = XElement.Load(file);
XElement sms = root.XPathElement("//Sms[#tip={0}]", "VF"); // or "//Sms[#tip='VF']"
By using it with string.Format() syntax, you pass the type to the XPath as well, if you wanted to do a DateTime check, etc. I also find it easier for variable injections as well, instead of "//Sms[#tip='" + variable + "']". XPathElement is just XPath().FirstOrDefault() to return a single element.