具有非 ConfigurationElement 属性的自定义配置部分
Custom config section with non-ConfigurationElement properties
我有一个工作自定义配置部分。但是,通过 ConfigurationElementCollection
获取我的数据很痛苦,但是当我尝试将我的 属性 实现为 IEnumerable 时,它失败并显示错误:
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>
?
以防万一,我正在尝试存储电子邮件,并且我希望每个元素都有一个元素,因为它们可能有很多,我们可能希望在future,我认为单个逗号分隔的列表可能会变得丑陋。例如,类似于:
<emergency>
<contact address="sirdank@whosebug.com" />
<contact address="jon.skeet@whosebug.com" />
</emergency>
或
<emergency>
<contact>sirdank@whosebug.com</contact>
<contact>jon.skeet@whosebug.com</contact>
</emergency>
谢谢!
提供两种方法有什么坏处吗?第一个满足 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"]); }
}
如果您只需要一个字符串列表,一个解决方案是声明一个以逗号分隔(或任何分隔符)的值列表,如下所示:
[ConfigurationProperty("contacts")]
[TypeConverter(typeof(StringSplitConverter))]
public IEnumerable<string> Contacts
{
get
{
return (IEnumerable<string>)base["contacts"];
}
}
有了这个TypeConverter class:
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 的回答一样。
我有一个工作自定义配置部分。但是,通过 ConfigurationElementCollection
获取我的数据很痛苦,但是当我尝试将我的 属性 实现为 IEnumerable 时,它失败并显示错误:
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>
?
以防万一,我正在尝试存储电子邮件,并且我希望每个元素都有一个元素,因为它们可能有很多,我们可能希望在future,我认为单个逗号分隔的列表可能会变得丑陋。例如,类似于:
<emergency>
<contact address="sirdank@whosebug.com" />
<contact address="jon.skeet@whosebug.com" />
</emergency>
或
<emergency>
<contact>sirdank@whosebug.com</contact>
<contact>jon.skeet@whosebug.com</contact>
</emergency>
谢谢!
提供两种方法有什么坏处吗?第一个满足 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"]); }
}
如果您只需要一个字符串列表,一个解决方案是声明一个以逗号分隔(或任何分隔符)的值列表,如下所示:
[ConfigurationProperty("contacts")]
[TypeConverter(typeof(StringSplitConverter))]
public IEnumerable<string> Contacts
{
get
{
return (IEnumerable<string>)base["contacts"];
}
}
有了这个TypeConverter class:
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 的回答一样。