关于C#:自定义app.config列表在applicationconfiguration.getsection()上产生错误

Custom app.config list producing error on ApplicationConfiguration.GetSection()

背景:尝试按照以下示例在app.config中实现列表:

  • http://jopinblog.wordpress.com/2007/04/20/custom-configurationsections-in-net-20-config-files/
  • http://social.msdn.microsoft.com/forums/en/csharpgeneral/thread/0f3557ee-16bd-4a36-a4f3-00efbeae9b0d
  • 带有"添加"元素的简单列表的自定义app.config部分
  • app.config的自定义配置-节的集合?

目标:我正在寻求解决此错误并使其正常工作。

错误:

Unrecognized element 'lookupMapping'. (C: ...line 75)

调试过程中在此行上产生错误:

lookupMappingConfigSection部分=(lookupMappingConfigSection)config.sections["lookupMappings"];

app.config代码段:

1
2
3
4
5
6
7
8
9
10
11
<configuration>
  <configSections>
    <section name="lookupMappings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.30319.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
  </configSections>
  <lookupMappings>
    <lookupMapping name="One" lookupName="foo" />
    <lookupMapping name="Two" lookupName="foo" />
    <lookupMapping name="Three" lookupName="foo" />
    <lookupMapping name="Four" lookupName="foo" />
  </lookupMappings>
</configuration>

Classes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class LookupMappingsInstanceElement : ConfigurationElement
{
    [ConfigurationProperty("name", IsRequired = true)]
    public string Name
    {
        get { return (string)base["name"]; }
        set { base["name"] = value; }
    }

    [ConfigurationProperty("lookupName", IsRequired = true)]
    public string LookupName
    {
        get { return (string)base["lookupName"]; }
        set { base["lookupName"] = value; }
    }
}

public class LookupMappingsConfigSection: ConfigurationSection
{
    [ConfigurationProperty("lookupMappings", IsDefaultCollection = true, IsRequired = true)]
    [ConfigurationCollection(typeof(LookupMappingsConfigCollection), AddItemName ="lookupMapping")]
    public LookupMappingsConfigCollection Instances
    {
        get { return (LookupMappingsConfigCollection) this[""]; }
        set { this[""] = value; }
    }
}

public class LookupMappingsConfigCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new LookupMappingsInstanceElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((LookupMappingsInstanceElement) element).Name;
    }

    public LookupMappingsInstanceElement this[int idx]
    {
        get { return (LookupMappingsInstanceElement)BaseGet(idx); }
    }

    public override ConfigurationElementCollectionType CollectionType
    {
        get { return ConfigurationElementCollectionType.BasicMap; }
    }

    protected override string ElementName
    {
        get { return"lookupMapping"; }
    }
}

实施C:

1
2
3
4
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
LookupMappingsConfigSection section = (LookupMappingsConfigSection)config.Sections["lookupMappings"]; // <--ERROR ON THIS LINE
LookupMappingsInstanceElement entry1 = section.Instances[0];
LookupMappingsInstanceElement entry2 = section.Instances[1];


好啊。根据帖子,我的名称空间和程序集在app.config部分中是不正确的。我还必须在app.config中添加一个额外的分组,这样它才能很好地播放。这是我的最终产品,以防它帮助其他人。

App.CONFIG

1
2
3
4
5
6
7
8
9
10
11
12
13
<configuration>
  <configSection>
    <section name="LookupMappingsSection" type="your.namespace.LookupMappingsConfigSection, your.assembly"/>
  </configSections>
  <LookupMappingsSection>
    <LookupMappings>
     
     
     
     
    </LookupMappings>
  </LookupMappingsSection>
</configuration>

C类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class LookupMappingsConfigSection: ConfigurationSection
{
    [ConfigurationProperty("LookupMappings")]
    public LookupMappingsConfigCollection LookupMappings
    {
        get { return ((LookupMappingsConfigCollection)(base["LookupMappings"])); }
    }
}

[ConfigurationCollection(typeof(LookupMappingElement))]
public class LookupMappingsConfigCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new LookupMappingElement();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((LookupMappingElement) element).Name;
    }

    public LookupMappingElement this[int idx]
    {
        get { return (LookupMappingElement)BaseGet(idx); }
    }

}

public class LookupMappingElement : ConfigurationElement
{
    [ConfigurationProperty("name", DefaultValue ="",IsKey = true)]
    public string Name
    {
        get { return (string)base["name"]; }
        set { base["name"] = value; }
    }

    [ConfigurationProperty("lookupName", DefaultValue ="", IsKey = false, IsRequired = false)]
    public string LookupName
    {
        get { return (string)this["lookupName"]; }
        set { base["lookupName"] = value; }
    }
}

//Get the lookup entries
LookupMappingsConfigSection section = (LookupMappingsConfigSection)ConfigurationManager.GetSection("LookupMappingsSection");
foreach(LookupMappingElement lookupMapping in section.LookupMappings)
{
    //Do something
}

主要问题是,您正试图将您的lookupMappings部分作为标准AppSettingsSection加载。将配置文件更改为:

1
2
3
4
5
6
7
8
9
10
11
<configuration>
  <configSections>
    <section name="lookupMappings" type="Fully.Qualified.Type.Of.LookupMappingsConfigSectionType, Name.Of.Assembly.Containing.LookupMappingsConfigSectionType"/>
  </configSections>
  <lookupMappings>
    <lookupMapping name="One" lookupName="foo" />
    <lookupMapping name="Two" lookupName="foo" />
    <lookupMapping name="Three" lookupName="foo" />
    <lookupMapping name="Four" lookupName="foo" />
  </lookupMappings>
</configuration>

NOTE: You'll need to replace Fully.Qualified.Type.Of.LookupMappingsConfigSectionType and Name.Of.Assembly.Containing.LookupMappingsConfigSectionType with the appropriate type and assembly names.


配置节定义无效。它应该指向实现lookupMappingConfigSection的完全限定名。

1
2
3
4
5
6
7
8
9
10
11
<configuration>
  <configSections>
    <section name="lookupMappings" type="MyAssembly.Namespace.LookupMappingsConfigSection, MyAssembly"/>
  </configSections>
  <lookupMappings>
    <lookupMapping name="One" lookupName="foo" />
    <lookupMapping name="Two" lookupName="foo" />
    <lookupMapping name="Three" lookupName="foo" />
    <lookupMapping name="Four" lookupName="foo" />
  </lookupMappings>
</configuration>

自定义配置部分的名称空间是什么?

我从你写的配置文件中看到:

1
type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.30319.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

这不应该是这样的吗?

1
type="your.namespace.LookupMappingsConfigSection, your.assembly" ?

对于自定义配置节,还可以签出配置节设计器