2016-02-27 92 views
2

這不是一個新問題,但我一直在研究這兩天,所有我能找到的答案都是過時的或無益的。我想要做的是將一個對象放入App.config中,然後在程序啓動時加載它。 (字符串)名字,(字符串)姓氏和(int)年齡。我有一個基本的類稱爲「人」與三個自動屬性:(字符串)名字,(字符串)姓和(int)年齡。這是我的App.config文件:如何從app.config中讀取對象?

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup> 
    <configSections> 
    <sectionGroup name="People"> 
     <section 
     name="Person" 
     type="Person.Person" 
     /> 
    </sectionGroup> 
    </configSections> 
    <People> 
    <Person> 
     <Person type="Person.Person, Person"> 
     <FirstName>Jimmy</FirstName> 
     <LastName>Dean</LastName> 
     <Age>2</Age> 
     </Person> 
    </Person> 
    </People> 
</configuration> 

這裏是我的程序:

using System; 
using System.Configuration; 

namespace AppConfigTest 
{ 
    class AppConfigTester 
    { 
     public static void Main(string[] args) 
     { 
      var guy = (Person.Person) ConfigurationManager.GetSection("People/Person"); 
      Console.WriteLine(guy.FirstName); 
      Console.WriteLine(guy.LastName); 
      Console.WriteLine(guy.Age); 
     } 
    } 
} 

在其與ConfigurationErrorsException崩潰的時刻。任何幫助將非常感激。當App.config應該讓這樣的事情變得更簡單時,我覺得這太難了。

+1

你在哪裏定義自定義配置部分? https://msdn.microsoft.com/en-us/library/2tw134k3.aspx – David

+0

@David這是我錯過了什麼?我之前有一個,基於棄用的ConfigurationSettings,最終取消了它。在這一點上我很困惑。我會盡力做一個新的。 – randomraccoon

回答

4

給定一個人POCO類:

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int Age { get; set; } 
} 

首先,你需要ŧ Ø創建一個繼承System.Configuration.ConfigurationElement像這樣一類:

public class PersonElement : ConfigurationElement 
{ 
    public string InnerText { get; private set; } 

    protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) 
    { 
     InnerText = reader.ReadElementContentAsString(); 
    } 
} 

這是必要的,所以你可以有配置元素,如<FirstName>Jimmy</FirstName>與內部文本。

接下來,你需要一個類繼承System.Configuration.ConfigurationSection這樣的:

public class PersonSection : ConfigurationSection 
{ 
    [ConfigurationProperty("FirstName")] 
    public PersonElement FirstName 
    { 
     get { return this["FirstName"] as PersonElement; } 
     set { this["FirstName"] = value; } 
    } 

    [ConfigurationProperty("LastName")] 
    public PersonElement LastName 
    { 
     get { return this["LastName"] as PersonElement; } 
     set { this["LastName"] = value; } 
    } 

    [ConfigurationProperty("Age")] 
    public PersonElement Age 
    { 
     get { return this["Age"] as PersonElement; } 
     set { this["Age"] = value; } 
    } 

    public Person CreatePersonFromConfig() 
    { 
     return new Person() 
     { 
      FirstName = this.FirstName.InnerText, 
      LastName = this.LastName.InnerText, 
      Age = Convert.ToInt32(this.Age.InnerText) 
     }; 
    } 
} 

你的app.config應該是這樣的:

<configuration> 
    <configSections> 
     <sectionGroup name="People"> 
      <section name="Person" type="Example.PersonSection, Example" /> 
     </sectionGroup> 
    </configSections> 
    <People> 
     <Person> 
      <FirstName>Jimmy</FirstName> 
      <LastName>Dean</LastName> 
      <Age>2</Age> 
     </Person> 
    </People> 
</configuration> 

最後地方在你的代碼做到這一點:

PersonSection config = (PersonSection)ConfigurationManager.GetSection("People/Person"); 
Person guy = config.CreatePersonFromConfig(); 
+2

哇,謝謝!我不知道我需要那個PersonElement類。這種學習曲線對我來說非常陡峭,所以我非常感謝幫助。 – randomraccoon

1

有幾個與你的執行問題,它們是:

  1. <configSections>元素必須是第一個元素在你的App.config文件
  2. 配置節處理程序(即在上述類型type屬性的section元素)必須從ConfigurationSection繼承。
  3. 完全合格的,你指的是

<configSections>元素的類型必須是第一個元素在你的App.config文件

正被拋出的ConfigurationErrorsException包含以下細節:

只有一個< configSections>元素允許每個配置文件,如果存在必須是根的第一個孩子<配置>元素。

這就是說你必須將<configSections>元素移動到文件的頂部。我想這是這樣的,處理配置文件的代碼可以在之前的每個區段加載相應的處理程序它讀取配置文件的每個部分。

配置節處理程序(即在section元素的type屬性描述的類型),必須從ConfigurationSection

不幸的是,配置系統的工作方式繼承意味着你不能只刪除一個POCO請注意爲您配線。有一個教程creating a custom configuration section on MSDN

完全合格的,你指的是

我不知道,這其實是造成你的問題的類型,但它不會傷害要精確,以避免它造成的一個問題。以下內容:

<section name="Person" type="Person.Person" /> 

可能含糊不清。假設你的項目編譯名爲「MyProjectThatContainsPerson」一個DLL/EXE,你應該考慮將其更改爲:

<section name="Person" type="Person.Person, MyProjectThatContainsPerson" /> 

這清楚的配置系統不僅什麼類型的名稱是(Person.Person),但還應該嘗試從(MyProjectThatContainsPerson)加載它的組件。

一個例子定製部分使用內置節處理

如果你想補充一點,有一個自定義名稱的構成部分(例如,「MySection」),但在其他方面的表現一樣appSettings,你可以有:

<configSections> 
    <section name="MySection" 
      type="System.Configuration.NameValueSectionHandler, system, 
        Version=1.0.3300.0, Culture=neutral, 
        PublicKeyToken=b77a5c561934e089, Custom=null" /> 
</configSections> 
<MySection> 
    <add key="MySetting" value="MyValue" /> 
</MySection>