简体   繁体   English

app.config中的嵌套自定义元素(C#)

[英]Nested custom elements in app.config (C#)

G'da to everyone, G'da给大家,

For hours I've been trying to figure how to read settings from app.config file: 几个小时以来,我一直试图想出如何从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>

The the code for custom handler classes is here , also copied below: 自定义处理程序类的代码在这里 ,也复制如下:

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; }
    }
}

The problem is when I attempt to get "Databases" section via GetSection method: 问题是当我尝试通过GetSection方法获取“数据库”部分时:

Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
DatabaseSection DbConfig = Config.GetSection("Databases") as DatabaseSection;

program throws an ConfigurationErrorsException, reporting "Unrecognized element 'Database'", although it does that after going through get method of DatabaseSection, even though I define AddItemName for DatabaseInstanceCollection as "Database". 程序抛出一个ConfigurationErrorsException,报告​​“无法识别的元素'数据库'”,虽然它是在通过DatabaseSection的get方法后执行的,即使我将DatabaseInstanceCollection的AddItemName定义为“数据库”。 Am I missing something, attribute that will let underlying code read the app.config correctly? 我错过了什么属性,让底层代码正确读取app.config?

Obligatory links: 必要的链接:

After a cursory look it seems like your problem is on this line: 粗略看一下,你的问题似乎就在这条线上:

[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "add", CollectionType = ConfigurationElementCollectionType.BasicMap )]

This indicates that the .config file should look like this: 这表明.config文件应如下所示:

<Databases>
    <add><!-- Database goes here --></add>
</Databases>

Ie your Databases element is expecting an "add" child, to indicate that an item is to be added to the colleciton. 即您的Databases元素期望一个“add”子元素,表示要将一个项目添加到colleciton。

You should try changing the AddItemName property from "add" to "Database": 您应该尝试将AddItemName属性从“添加”更改为“数据库”:

[ConfigurationCollection(typeof(DatabaseElement), AddItemName = "Database", CollectionType = ConfigurationElementCollectionType.BasicMap )]

(I've not had a chance to test this, there may be other problems) (我没有机会测试这个,可能还有其他问题)

You're correct, Kragen, I had to remove Table/ColumnSection and add Table/ColumnInstanceCollection to Database/TableElement. 你是对的,Kragen,我必须删除Table / ColumnSection并将Table / ColumnInstanceCollection添加到Database / TableElement。 DatabaseSection' Databases property had to be like: DatabaseSection'数据库属性必须像:

[ConfigurationProperty("", IsDefaultCollection = true)]
        public DatabaseInstanceCollection Databases
        {
            get { return (DatabaseInstanceCollection)this[""]; }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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