2011-04-07 114 views
5

G'da給大家,嵌套自定義元素

幾個小時我一直在試圖找出如何從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方法去,即使我定義爲AddItemName作爲DatabaseInstanceCollection「數據庫」之後。我是否錯過了一些可以讓底層代碼正確讀取app.config的屬性?

+2

SO格式化有什麼問題?此外,你需要爲此做更多的工作。描述什麼不適合你,以及你的問題是什麼。沒有人會通讀你的代碼來弄清楚哪裏出了問題。舉例說明你的失敗。 – 2011-04-07 04:41:16

+1

您是否問過如何使用您定義的類在配置設置中讀取?我沒有在你的代碼中看到任何你真正閱讀過的東西。 – 2011-04-07 04:43:02

+0

如果你想發佈**代碼,XML **或** data **樣本,在文本編輯器中突出顯示這些行,然後單擊「代碼(編輯器)工具欄上的「樣本」按鈕(「{}」),以精確地格式化和語法突出顯示它!如果你願意,SO **會**格式化並顯示出來! – 2011-04-07 04:52:11

回答

7

強制性鏈接:

匆匆一瞥,好像你的問題後,在這條線:

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

這表示.config文件應該如下所示:

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

I.e.您的Databases元素期望有一個「添加」子元素,表示要將某個項目添加到該集合中。

你應該嘗試從「添加」到「數據庫」改變AddItemName屬性:

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

(我沒有機會來測試這一點,有可能是其他問題)

+0

謝謝Kragen,我瀏覽了類似的應用程序配置的Q&A。NET在這裏,並訪問過你之前提到的鏈接,但唉。我試圖將AddItemName更改爲「數據庫」,但無濟於事。 我有一個懷疑,「數據庫」元素必須聲明的部分「數據庫」,雖然我會認爲它通過ConfigurationCollection屬性的「AddItemName」屬性完成。 – 2011-04-08 00:24:45

+1

@ user696034它對錯誤消息有影響嗎?我也發現'DatabaseElement'配置元素沒有引用'TableSection'配置部分,所以我認爲即使解決了上述問題,也可能會導致失敗。 – Justin 2011-04-08 00:53:10

+1

我已經設法讓整個事情發展,但你是正確的Kragen,有必要將TableInstanceCollection添加到DatabaseElement和ColumnInstanceCollection TableElement。 另外,DatabaseSection必須像這樣工作: – 2011-04-08 01:16:45

1

你'正確,Kragen,我必須刪除Table/ColumnSection並將Table/ColumnInstanceCollection添加到Database/TableElement。 DatabaseSection'數據庫屬性必須是這樣的:

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