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

发布于 2024-10-30 21:30:36 字数 4268 浏览 1 评论 0原文

大家好,

几个小时以来,我一直在尝试弄清楚如何从 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>

自定义处理程序类的代码位于此处,也复制如下:

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 的属性?

G'da to everyone,

For hours I've been trying to figure how to read settings from app.config file:

<?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:

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". Am I missing something, attribute that will let underlying code read the app.config correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ヤ经典坏疍 2024-11-06 21:30:36

必填链接:

粗略查看后,您的问题似乎出在这一行:

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

这表明 .config 文件应如下所示:

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

即您的 Databases 元素正在期待一个“add”子项,指示要将项目添加到集合中。

您应该尝试将 AddItemName 属性从“add”更改为“Database”:(

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

我没有机会测试这一点,可能还有其他问题)

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:

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

I.e. your Databases element is expecting an "add" child, to indicate that an item is to be added to the colleciton.

You should try changing the AddItemName property from "add" to "Database":

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

(I've not had a chance to test this, there may be other problems)

似梦非梦 2024-11-06 21:30:36

你是对的,Kragen,我必须删除 Table/ColumnSection 并将 Table/ColumnInstanceCollection 添加到 Database/TableElement。 DatabaseSection 的 Databases 属性必须类似于:

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

You're correct, Kragen, I had to remove Table/ColumnSection and add Table/ColumnInstanceCollection to Database/TableElement. DatabaseSection' Databases property had to be like:

[ConfigurationProperty("", IsDefaultCollection = true)]
        public DatabaseInstanceCollection Databases
        {
            get { return (DatabaseInstanceCollection)this[""]; }
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文