2016-07-05 23 views
4

我有一個工作的自定義配置節。然而,這是一個痛苦通過ConfigurationElementCollection但是當我試圖實現我的財產作爲一個IEnumerable,它失敗,出現錯誤,在我的數據獲取:具有非ConfigurationElement屬性的自定義配置節

ConfigurationErrorsException was unhandled "Property 'contacts' is not a ConfigurationElement."

這裏是代碼導致故障:

[ConfigurationProperty("contacts", IsDefaultCollection = false)] 
public IEnumerable<string> Contacts 
{ 
    get { return ((ContactCollection)base["contacts"]).Cast<ContactElement>().Select(x => x.Address); } 
} 

但是,如果我把它改成這樣:

[ConfigurationProperty("contacts", IsDefaultCollection = false)] 
public ContactCollection Contacts 
{ 
    get { return ((ContactCollection)base["contacts"]); } 
} 

,一切工作正常。 This答案聽起來像這只是微軟決定不允許的東西,所以我不能有除ConfigurationElement以外的任何其他類型的屬性。這是真的嗎?我如何才能以IEnumerable<string>實現我的財產?

萬一它很重要,我正在嘗試存儲電子郵件,並且我希望爲每個電子郵件分配一個元素,因爲可能會有多個元素,我們可能會在將來爲每個聯繫人存儲更多信息,我認爲一個以逗號分隔的列表可能會變得很難看。例如,像:

<emergency> 
    <contact address="[email protected]" /> 
    <contact address="[email protected]" /> 
</emergency> 

或者

<emergency> 
    <contact>[email protected]</contact> 
    <contact>[email protected]</contact> 
</emergency> 

謝謝!

+0

你有我的同情心。自定義配置節與嵌套集合是一個巨大的痛苦。我已經寫了很多,但我仍然記不起語法來提供答案。也許這篇文章會幫助:[http://stackoverflow.com/questions/10958054/how-to-create-a-configuration-section-that-c​​ontains-a-collection-of-collections](http://stackoverflow。 com/questions/10958054/how-to-create-a-configuration-section-that-c​​ontain-a-collection-of-collections) –

+1

在我看來,大部分複雜性來自於支持以編程方式更新的部分支持覆蓋較低級別的配置文件。這很棒,但實際上我們很少使用它。說我們從不*使用它可能是安全的。 –

回答

3

提供兩種方法有什麼不好嗎?第一個滿足Microsoft要求,第二個滿足您自己的要求。

public IEnumerable<string> Contacts 
    { 
     get 
     { 
      return ContactCollection.Cast<ContactElement>().Select(x => x.Address);  
     } 
    } 

    [ConfigurationProperty("contacts", IsDefaultCollection = false)] 
    public ContactCollection ContactCollection 
    { 
     get { return ((ContactCollection)base["contacts"]); } 
    } 
+0

我想避免這樣做,但我不知道爲什麼有人低估了你。如果這是唯一的解決方案,我將來會接受它。此外,感謝您在這裏待了五年後的第一個答案! :) – sirdank

+1

請注意,如果您要屏蔽呼叫者和智能感知的屬性,則甚至可以將ContactCollection聲明爲私人,這很有趣。 –

+0

哈哈...我的第一個答案,我立即被低估了!我很害怕; – Will

1

一個解決方案,如果你只需要串的名單,正在申報價值的這樣一個逗號分隔(或分離)名單:

[ConfigurationProperty("contacts")] 
    [TypeConverter(typeof(StringSplitConverter))] 
    public IEnumerable<string> Contacts 
    { 
     get 
     { 
      return (IEnumerable<string>)base["contacts"]; 
     } 
    } 

有了這個TypeConverter類:

public class StringSplitConverter : TypeConverter 
{ 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
    { 
     return string.Format("{0}", value).Split(','); 
    } 
} 

你的config文件將隨後簡單地聲明如下:

<configuration> 
    ... 
    <mySection contacts="bill,joe" /> 
    ... 
</configuration> 

注意這不適用於集合,當你總是需要顯式聲明一個屬性時,就像Will的答案一樣。

相關問題