假设我有一个看起来像这样的配置属性。请注意,没有默认值。
[ConfigurationProperty("x", IsRequired = true)]
[StringValidator(MinLength = 1)]
public string X
{
get { return (string)this["x"]; }
set { this["x"] = value; }
}
现在我添加我的部分:
<mySection x="123" />
我会收到此错误:
属性'x'的值不是 有效。错误是:字符串必须 至少1个字符。
如果我将配置属性更改为包含如下默认值:
[ConfigurationProperty("x", DefaultValue="abc", IsRequired = true)]
[StringValidator(MinLength = 1)]
public string X
{
get { return (string)this["x"]; }
set { this["x"] = value; }
}
这意味着即使IsRequired为true,验证器也会验证默认值。这也意味着我必须在我的所有属性上包含一个虚拟默认值才能通过验证,即使它们实际上不会被使用。
这只是糟糕的设计还是有这种行为的正当理由?
答案 0 :(得分:7)
我以前遇到过这个问题。这是有正当理由但我不记得细节。
我不记得这是否有效,但您可以尝试在构造函数中声明属性,其中null是默认值。
public class CustomConfigurationSection : ConfigurationSection
{
public CustomConfigurationSection()
{
Properties.Add(new ConfigurationProperty(
"x",
typeof(string),
null,
null,
new StringValidator(1),
ConfigurationPropertyOptions.IsRequired));
}
public string X
{
get { return (string)this["x"]; }
set { this["x"] = value; }
}
}
这与使用默认值和验证器有关,但是需要默认值。 http://msdn.microsoft.com/en-us/library/system.configuration.configurationproperty(VS.85).aspx#1
修改
我刚试过以前的代码,它就像我预期的那样。我之前的代码没有编译,因为我错过了一个构造函数属性,所以我修复了它。
答案 1 :(得分:3)
原因是配置节类可以在代码中新建,而不需要配置文件。您可以使用默认构造函数,而不指定属性的任何值。在这种情况下,即使您指定了IsRequired=true
,也不会抛出异常。换句话说,IsRequired
仅在从XML反序列化属性时才适用。
但是,DefaultValue
在这种情况下适用,就像从XML反序列化属性时一样(与任何ConfigurationValidatorAttribute
一样)。
如果您在单元测试中使用配置部分,这是有意义的。 A)非常好A)在构造节时有一个声明性默认值,B)有默认值验证。
答案 2 :(得分:1)
根据我的理解,这种行为是非常必要的。
由于配置是任何应用程序的核心区域之一,并且假设没有为应用程序关键属性提供任何值,那么整个应用程序可能会导致一些不需要的行为(可能是崩溃,无限期的资源利用等) )。我认为这就是原因,大多数.Net内置配置属性(如会话超时等)都设置为默认值,即使用户没有指定值,也会应用它们。
答案 3 :(得分:0)
如前所述,这在不必为属性指定默认值的情况下无助于进行验证,这样会使ConfigurationPropertyAttribute的IsRequired属性无效。