简体   繁体   中英

ConfigurationManager.GetSection doesn't return custom section

Because my new project has a complex configuration structure I'm learning how to use class ConfigurationManager with Custom Configurations.

To do this, I used MSDN How to: Create Custom Configuration Sections Using ConfigurationSection as an example. This example shows a configuration section for a class that aggregates other configurable classes.

MyProblem: ConfigurationManager.GetSection does not return a section

I created a ConsoleApplication.

  • Namespace: TryConfigManagement
  • Add reference: System.Configuration
  • Changed App.Config (copy always) as follows:

     <?xml version="1.0" encoding="utf-8"?> <configuration> <!-- Configuration section-handler declaration area. --> <configSections> <sectionGroup name="pageAppearanceGroup"> <section name="pageAppearance" type="TryConfigManagement.PageAppearance" allowLocation="true" allowDefinition="Everywhere" /> </sectionGroup> </configSections> <!-- Configuration section settings area. --> <pageAppearanceGroup> <pageAppearance remoteOnly="true"> <font name="TimeNewRoman" size="18"/> <color background="000000" foreground="FFFFFF"/> </pageAppearance> </pageAppearanceGroup> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/> </startup> </configuration> 

Note that I used a configuration group as in the example from MSDN.

My source code:

namespace TryConfigManagement
{
    class Program
    {
        static void Main(string[] args)
        {
            string sectionName = "pageAppearanceGroup/pageAppearance";
            object section = ConfigurationManager.GetSection(sectionName);

This piece of code throws the following exception:

An error occurred creating the configuration section handler
for pageAppearanceGroup/pageAppearance:
Could not load type 'TryConfigManagement.PageAppearanceSection'
from assembly 'System.Configuration, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
(C:\...\bin\Debug\TryConfigManagement.vshost.exe.config line 6)

Although I did exactly what was in the example I figured out from StackOverflow that I should add the assembly information, probably like below:

class Program
{
    static void Main(string[] args)
    {
        var assembly = Assembly.GetExecutingAssembly();
        string sectionName = "pageAppearanceGroup/pageAppearance ," +
            assembly.FullName;
        object section = ConfigurationManager.GetSection(sectionName);

Now the exception is not thrown anymore, but the returned value is null.

I think it has to do with the type in the section name of the config file. However trying different values like adding full assembly name didn't help.

Alas I can't find a lot of information about the string parameter in GetSection.

So what is wrong with my app.config, or with my GetSection call?

You can try to specify the assembly where TryConfigManagement.PageAppearance type is located in your config:

 <sectionGroup name="pageAppearanceGroup">
      <section
        name="pageAppearance"
        type="TryConfigManagement.PageAppearance, TryConfigManagement"
        allowLocation="true"
        allowDefinition="Everywhere"
        />
    </sectionGroup>

Then don't include the assembly name in GetSection parameter.

Also, remove the space after your section name.

Smiech's comment about case sensitivity helped (thanx Smiech!), but it was not the complete answer.

Instead of magic string handling like "pageAppearanceGroup/pageAppearance it is much easier to read and maintain if the classes ConfigurationSectionGroupCollection and ConfigurationSectionCollection are used.

The code would look like follows:

namespace MyNameSpace
{
    class Program
    {
        static void Main(string[] args)
        {
            const string configGroupName = "pageAppearanceGroup";
            const string configSectionName = "pageAppearance";

            Configuration config =  ConfigurationManager.OpenExeConfiguration (ConfigurationUserLevel.None);
            ConfigurationSectionGroup configGroup = config.SectionGroups[configGroupName];
            PageAppearanceSection pageAppearanceConfig = (PageAppearanceSection)configGroup.Sections[configSectionName];

After these I could perform the following statements:

Console.WriteLine("PageAppearance property values:");
Console.WriteLine("RemoteOnly = " + pageAppearanceConfig.RemoteOnly);
Console.WriteLine("Font: Name = {0}, Size = {1}",
    pageAppearanceConfig.Font.Name,
    pageAppearanceConfig.Font.Size);
Console.WriteLine("Color: Foreground {0}, Background {1}",
    pageAppearanceConfig.Color.Foreground,
    pageAppearanceConfig.Color.Background);

Note: To understand the App.Config I changed the namespace into MyNameSpace. The assembly name is still TryConfigManagement

For completeness the contents of App.Config. Note where the namespace and assembly name are used

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <!-- Configuration section-handler declaration area.  -->
      <configSections>
        <sectionGroup name ="pageAppearanceGroup">
          <section name="pageAppearance"
                   type ="TryConfigManagement.PageAppearanceSection, TryConfigManagement"
                   allowLocation="true"
                   allowDefinition="Everywhere"
                   />
        </sectionGroup>
      </configSections>

      <!-- Configuration section settings area. -->
      <pageAppearanceGroup>
         <pageAppearance>
          <font name="TimeNewRoman" size="18"/>
          <color background="000000" foreground="FFFFFF"/>
        </pageAppearance>  
      </pageAppearanceGroup>
    </configuration>

The fields of the section definition:

  • name of the setting in the configuration settings area. Must be in the same settings group
  • type: the actual type of ( the derived class of) the configurationSection. This includes the namespace. After the semicolon comes the assembly name. This doesn't have to be the full assemblyName

Now all I have to do if find a method to get rid of all the magic strings. But that's a different matter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM