app.config (C#) 中的嵌套自定义元素
Posted
技术标签:
【中文标题】app.config (C#) 中的嵌套自定义元素【英文标题】:Nested custom elements in app.config (C#) 【发布时间】:2011-07-31 08:36:36 【问题描述】:祝大家,
几个小时以来,我一直试图弄清楚如何从 app.config 文件中读取设置:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="Databases" type="McFix.DatabaseSection, McFix"/>
</configSections>
<Databases>
<Database name="database">
<Tables>
<Table name="be_sessions">
<Columns>
<Column name="sess_id">
</Column>
</Columns>
</Table>
</Tables>
</Database>
</Databases>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
自定义处理程序类的代码是here,也复制如下:
public class DatabaseSection : ConfigurationSection
[ConfigurationProperty("Databases", IsDefaultCollection = false)]
public DatabaseInstanceCollection Databases
get return (DatabaseInstanceCollection)this["Databases"];
set this[""] = value;
[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "add", CollectionType = ConfigurationElementCollectionType.BasicMap )]
public class DatabaseInstanceCollection : ConfigurationElementCollection
protected override ConfigurationElement CreateNewElement()
return new DatabaseElement();
protected override object GetElementKey(ConfigurationElement element)
return ((DatabaseElement)element).Name;
public class DatabaseElement : ConfigurationElement
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
get return (string)base["name"];
set base["name"] = value;
public class TableSection : ConfigurationSection
[ConfigurationProperty("Tables", IsDefaultCollection = true)]
public TableInstanceCollection Tables
get return (TableInstanceCollection)this["Tables"];
set this[""] = value;
[ConfigurationCollection(typeof(TableElement), AddItemName = "Table", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class TableInstanceCollection : ConfigurationElementCollection
protected override ConfigurationElement CreateNewElement()
return new TableElement();
protected override object GetElementKey(ConfigurationElement element)
return ((TableElement)element).Name;
public class TableElement : ConfigurationElement
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
get return (string)base["name"];
set base["name"] = value;
public class ColumnSection : ConfigurationSection
[ConfigurationProperty("Columns", IsDefaultCollection = true)]
public ColumnInstanceCollection Columns
get return (ColumnInstanceCollection)this["Columns"];
set this[""] = value;
[ConfigurationCollection(typeof(ColumnElement), AddItemName = "Column", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class ColumnInstanceCollection : ConfigurationElementCollection
protected override ConfigurationElement CreateNewElement()
return new ColumnElement();
protected override object GetElementKey(ConfigurationElement element)
return ((ColumnElement)element).Name;
public class ColumnElement : ConfigurationElement
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
get return (string)base["name"];
set base["name"] = value;
问题是当我尝试通过 GetSection 方法获取“数据库”部分时:
Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
DatabaseSection DbConfig = Config.GetSection("Databases") as DatabaseSection;
程序抛出一个 ConfigurationErrorsException,报告“无法识别的元素'数据库'”,尽管它在通过 DatabaseSection 的 get 方法之后这样做,即使我将 DatabaseInstanceCollection 的 AddItemName 定义为“数据库”。我是否遗漏了一些能让底层代码正确读取 app.config 的属性?
【问题讨论】:
SO 格式有什么问题?此外,您需要为此做更多的工作。描述什么对你不起作用以及你的问题是什么。没有人会通读您的代码以找出问题所在。举出你失败的例子。 您是否在询问如何使用您定义的类读取配置设置?我在您的代码中没有看到您实际阅读的任何内容。 如果您想发布 code、XML 或 data 示例,请在文本编辑器中突出显示这些行并单击“code samples”按钮(
)在编辑器工具栏上很好地格式化和语法高亮它!如果您这样做,那么将格式化并很好地显示它!
我向大家道歉,有一段时间没有在论坛上发布问题(主要是因为我正在回答其他人的问题),我失去了联系。
【参考方案1】:
必填链接:
Unraveling the Mysteries of .NET 2.0 Configuration Decoding the Mysteries of .NET 2.0 Configuration Cracking the Mysteries of .NET 2.0 Configuration粗略一看,您的问题似乎出在这一行:
[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "add", CollectionType = ConfigurationElementCollectionType.BasicMap )]
这表示 .config 文件应如下所示:
<Databases>
<add><!-- Database goes here --></add>
</Databases>
即您的 Databases
元素需要一个“添加”子元素,以指示要将项目添加到集合中。
您应该尝试将AddItemName
属性从“add”更改为“Database”:
[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "Database", CollectionType = ConfigurationElementCollectionType.BasicMap )]
(我没有机会测试这个,可能还有其他问题)
【讨论】:
感谢 Kragen,我在这里浏览了 .NET 的类似应用程序配置的问答,并访问了您之前提到的链接,但唉。我试图将 AddItemName 更改为“数据库”,但也无济于事。我怀疑必须为“数据库”部分声明“数据库”元素,尽管我认为这是通过 ConfigurationCollection 属性的“AddItemName”属性完成的。 @user696034 它对错误消息有影响吗?我还发现DatabaseElement
配置元素没有引用TableSection
配置部分,因此我预计即使在解决上述问题后也可能会导致失败。
我已经设法让整个事情顺利进行,但你是对的 Kragen,有必要将 TableInstanceCollection 添加到 DatabaseElement 并将 ColumnInstanceCollection 添加到 TableElement。此外,DatabaseSection 必须像这样才能工作:【参考方案2】:
你说得对,Kragen,我必须删除 Table/ColumnSection 并将 Table/ColumnInstanceCollection 添加到 Database/TableElement。 DatabaseSection' Databases 属性必须是这样的:
[ConfigurationProperty("", IsDefaultCollection = true)]
public DatabaseInstanceCollection Databases
get return (DatabaseInstanceCollection)this[""];
【讨论】:
以上是关于app.config (C#) 中的嵌套自定义元素的主要内容,如果未能解决你的问题,请参考以下文章
C# 如何添加自定义键盘处理事件 如何配置app.config ? | csharp key press event tutorial and app.config