I need to create a simple customized ConfigurationSection with an IEnumerable inside it.
I have read several articles and stackoverflow links, taking this as a simple example:
How to create custom config section in app.config?
So, I have this config file section inside a Console App:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="Disk"
type="ConsoleApplication1_ConfigurationEnumerable.PathsConfigSection"/>
</configSections>
<Disk>
<Paths>
<Path name="one" permission="1" />
<Path name="two" permission="2" />
<Path name="three" permission="3" />
</Paths>
</Disk>
</configuration>
Next I have this whole structure to manage the config section:
using System.Configuration;
namespace ConsoleApplication1_ConfigurationEnumerable
{
public class Path: ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return (string)this["name"];
}
}
[ConfigurationProperty("permission", IsRequired=true)]
public string Permission
{
get
{
return (string)this["permission"];
}
}
}
public class Paths: ConfigurationElementCollection
{
public Path this[int index]
{
get
{
return base.BaseGet(index) as Path;
}
set
{
if (base.BaseGet(index) != null) {
base.BaseRemoveAt(index);
}
this.BaseAdd(index, value);
}
}
protected override ConfigurationElement CreateNewElement()
{
return new Path();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Path)element).Name;
}
}
public class PathsConfigSection : ConfigurationSection
{
public static PathsConfigSection GetConfig()
{
//return (PathsConfigSection)System.Configuration.ConfigurationManager.GetSection("Disk") ?? new PathsConfigSection();
return (PathsConfigSection)System.Configuration.ConfigurationManager.GetSection("Paths") ?? new PathsConfigSection();
}
[ConfigurationProperty("Paths")]
public Paths Paths
{
get
{
object o = this["Paths"];
return o as Paths;
}
}
}
}
And here the program.cs using the whole thing:
using System;
namespace ConsoleApplication1_ConfigurationEnumerable
{
class Program
{
static void Main(string[] args)
{
var config = PathsConfigSection.GetConfig();
if (config == null || config.Paths.Count == 0)
{
Console.WriteLine("Is null or empty");
}
else
{
foreach (Path item in config.Paths)
{
Console.WriteLine("Item {0} with valuer {1}", item.Name, item.Permission);
}
}
}
}
}
The problem here is inside this two lines:
//return (PathsConfigSection)System.Configuration
// .ConfigurationManager.GetSection("Disk") ?? new PathsConfigSection();
return (PathsConfigSection)System.Configuration
.ConfigurationManager.GetSection("Paths") ?? new PathsConfigSection();
If I use the second one (uncommented above) it returns null.
If I use the commented one, then it throws an exception like this:
System.Configuration.ConfigurationErrorsException was unhandled
HResult=-2146232062 Message=An error occurred creating the
configuration section handler for Disk: Could not load type
‘ConsoleApplication1_ConfigurationEnumerable.PathsConfigSection’ from
assembly ‘System.Configuration, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a’.
(C:\Users\blackberry\Desktop\ConsoleApplication1_ConfigurationEnumerable\ConsoleApplication1_ConfigurationEnumerable\bin\Debug\ConsoleApplication1_ConfigurationEnumerable.vshost.exe.config
line 4) Source=System.Configuration BareMessage=An error occurred
creating the configuration section handler for Disk: Could not load
type ‘ConsoleApplication1_ConfigurationEnumerable.PathsConfigSection’
from assembly ‘System.Configuration, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a’.
Filename=C:\Users\blackberry\Desktop\ConsoleApplication1_ConfigurationEnumerable\ConsoleApplication1_ConfigurationEnumerable\bin\Debug\ConsoleApplication1_ConfigurationEnumerable.vshost.exe.config
Line=4 StackTrace:
at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String
configKey, Boolean& isRootDeclaredHere)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String
configKey, Boolean getLkg, Boolean checkPermission, Boolean
getRuntimeObject, Boolean requestIsHere, Object& result, Object&
resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String
configKey)
at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String
sectionName)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at ConsoleApplication1_ConfigurationEnumerable.PathsConfigSection.GetConfig()
in
C:\Users\blackberry\Desktop\ConsoleApplication1_ConfigurationEnumerable\ConsoleApplication1_ConfigurationEnumerable\Disk.cs:line
63
at ConsoleApplication1_ConfigurationEnumerable.Program.Main(String[]
args) in
C:\Users\blackberry\Desktop\ConsoleApplication1_ConfigurationEnumerable\ConsoleApplication1_ConfigurationEnumerable\Program.cs:line
9
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext
executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean
preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart() InnerException: System.TypeLoadException
HResult=-2146233054
Message=Could not load type ‘ConsoleApplication1_ConfigurationEnumerable.PathsConfigSection’ from
assembly ‘System.Configuration, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a’.
Source=System.Configuration
TypeName=ConsoleApplication1_ConfigurationEnumerable.PathsConfigSection
StackTrace:
at System.Configuration.TypeUtil.GetTypeWithReflectionPermission(IInternalConfigHost
host, String typeString, Boolean throwOnError)
at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.Init(RuntimeConfigurationRecord
configRecord, FactoryRecord factoryRecord)
at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.InitWithRestrictedPermissions(RuntimeConfigurationRecord
configRecord, FactoryRecord factoryRecord)
at System.Configuration.RuntimeConfigurationRecord.CreateSectionFactory(FactoryRecord
factoryRecord)
at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String
configKey, Boolean& isRootDeclaredHere)
InnerException:
Where is my fault ?
You need to use the Fully Qualified Assembly Name when specifying the class in the
configSectionstag:This assumes that the name of your assembly is
ConsoleApplication1. If you are still getting exceptions, you can determine the correct value using the the following code:BTW: Your namespace is odd. Naming standard suggest that you use the dot (
.) when separating namespace hierarchies: