13

假设我有一个看起来像这样的配置属性。请注意,没有默认值。

[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 为真,验证器也会验证默认值。这也意味着我必须在我的所有属性上包含一个虚拟默认值才能通过验证,即使它们实际上不会被使用。

这只是糟糕的设计还是这种行为有正当理由?

4

4 回答 4

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

编辑

我刚刚尝试了以前的代码,它按我的预期工作。我之前的代码没有编译,因为我错过了一个构造函数属性,所以我已经修复了它。

于 2010-09-19T08:48:46.747 回答
3

原因是配置节类可以在没有配置文件的情况下在代码中更新。您可以使用默认构造函数而不为该属性指定任何值。在这种情况下,即使您已指定IsRequired=true也不会引发异常。换句话说,IsRequired仅适用于从 XML 反序列化属性的情况。

但是,在这种情况下DefaultValue 确实适用,就像从 XML 反序列化属性时一样(就像 any 一样ConfigurationValidatorAttribute)。

如果您在单元测试中使用配置部分,这是有道理的。A) 在构造部分时有一个声明性的默认值,B) 验证了默认值,这真的很好。

于 2012-02-05T14:06:48.080 回答
0

据我了解,这种行为是非常必要的。

由于配置是任何应用程序的核心区域之一,并且假设没有为应用程序关键属性提供任何值,那么整个应用程序可能会导致一些不需要的行为(可能是崩溃、无限资源利用等)。我认为这就是原因,大多数 .Net 内置配置属性(如会话超时等)都设置为默认值,即使用户没有指定值,它们也会被应用。

于 2010-09-19T12:00:02.093 回答
0

如前所述,这无助于在不必为属性指定默认值的情况下获得验证,从而使 ConfigurationPropertyAttribute 的 IsRequired 属性变得无用。

于 2020-07-14T15:02:23.650 回答