我有个奇怪的问题...在我的代码中,无论我将IsRequired的值设置为false还是true,它都保持为false。但是,如果我放入一个DefaultValue,它可以工作吗?
不工作的代码是:
public class FtpSettingsSection : ConfigurationSection
{
[ConfigurationProperty("host", IsRequired = true)]
public HostElement Host
{
get { return (HostElement)this["host"]; }
set { this["host"] = value; }
}
}
public class HostElement : ConfigurationElement
{
[ConfigurationProperty("URL", IsRequired = true)]
public string URL
{
get { return (string)this["URL"]; }
set { this["URL"] = value; }
}
}其工作代码是:
public class FtpSettingsSection : ConfigurationSection
{
[ConfigurationProperty("host", DefaultValue = "", IsRequired = true)]
public HostElement Host
{
get { return (HostElement)this["host"]; }
set { this["host"] = value; }
}
}
public class HostElement : ConfigurationElement
{
[ConfigurationProperty("URL", DefaultValue = "", IsRequired = true)]
public string URL
{
get { return (string)this["URL"]; }
set { this["URL"] = value; }
}
}为什么我需要将DefaultValue设置为""?
发布于 2011-07-11 12:21:39
我也遇到了同样的问题,并在http://msdn.microsoft.com/en-us/library/system.configuration.configurationpropertyattribute%28v=vs.90%29.aspx#1找到了解决方案。关于ConfigurationPropertyAttribute的评论并不完全正确,但它解释了问题的基础:
应用于子对象(从ConfigurationElement派生)时,ConfigurationPropertyAttribute的IsRequired成员
不起作用。当子系统考虑父部分/元素的属性以确定定义了哪些配置属性时,它将为每个子元素创建一个新实例(具有适当类型),并将其存储在父元素的值列表中。稍后,当它验证是否指定了所有必需的属性时,它无法区分默认的初始化子元素和配置文件中显式包含的子元素。
最理想的解决方法是通过ConfigurationProperty类以编程方式声明所需的元素。这需要比声明性方法多得多的工作。另一个选择..。
据我所知,另一种选择是不正确的。
可以在ConfigurationProperty页面上找到编程模型的示例。通过在自定义元素的构造函数中声明所需的属性,并保持其他所有内容不变,我已经设法解决了这个问题。
我怀疑当你添加DefaultValue时,它实际上并不起作用,而是出于不同的原因抛出了一个异常。您必须深入到InnerException链的末端才能找到ConfigurationErrorsException。如果缺少必需的属性,正确的消息是“未找到必需的属性‘(C:\path\to\yourproject\bin\Debug\yourproject.vshost.exe.Config’。行##)”
当您提供空字符串缺省值时,配置子系统将尝试将该字符串解析为HostElement,但会失败。生成的行的消息为“无法解析属性‘ConfigurationErrorsException’的默认值。错误是:对象引用未设置为对象的实例。(C:\path\to\yourproject\bin\Debug\yourproject.vshost.exe.Config ConfigurationErrorsException ##)”
发布于 2014-07-19 09:52:33
挖出一条死线。但我无意中找到了解决这个问题的办法。
在自定义部分构造函数中,引用自定义元素的ElementInformation。通过这样做,您的自定义部分的另一个实例将在元素的上下文中创建。出于某些我不完全理解的原因,IsRequired属性是受尊重的。
public class FtpSettingsSection : ConfigurationSection
{
public FtpSettingsSection()
{
// force it to double load.
if (this.Host.ElementInformation.IsPresent) ;
}
[ConfigurationProperty("host", IsRequired = true)]
public HostElement Host
{
get { return (HostElement)this["host"]; }
set { this["host"] = value; }
}
}发布于 2014-06-30 19:59:18
很抱歉,身体解剖,但这个问题也打击了我,但以一种更奇怪的方式,我的解决方案也适用于所问的问题。
我实现了在不重新启动进程的情况下重新加载配置。当该过程开始时,IsRequired属性被“忽略”,并且ConfigurationElement被默默地初始化为默认值。但是,当重新加载配置时,IsRequired属性将受到尊重!所以我在进程启动时硬编码了重载配置,解决了丢失异常的问题!
伪码:
config = (SampleConfiguration)ConfigurationManager.GetSection(ConfigSectionName);
// <-- no exception thrown for missing required properties
ConfigurationManager.RefreshSection(ConfigSectionName);
config = (SampleConfiguration)ConfigurationManager.GetSection(ConfigSectionName);
// <-- exception thrown!https://stackoverflow.com/questions/4091693
复制相似问题