即使 IsRequired 为 true,为什么 ConfigurationValidator 也会验证 ConfigurationProperty 的默认值?

发布于 2024-09-24 08:41:26 字数 770 浏览 5 评论 0原文

假设我有一个如下所示的配置属性。请注意,没有默认值。

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

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

Let's say I have a configuration property that looks like this. Note that there is no default value.

[ConfigurationProperty("x", IsRequired = true)]
[StringValidator(MinLength = 1)]
public string X
{
    get { return (string)this["x"]; }
    set { this["x"] = value; }
}

Now I add my section like this:

<mySection x="123" />

I'll get this error:

The value for the property 'x' is not
valid. The error is: The string must
be at least 1 characters long.

It works if I change the configuration property to include a default like this:

[ConfigurationProperty("x", DefaultValue="abc", IsRequired = true)]
[StringValidator(MinLength = 1)]
public string X
{
    get { return (string)this["x"]; }
    set { this["x"] = value; }
}

This implies that validator validates the default value even if IsRequired is true. It also means that I have to include a dummy default values on all my properties to pass validation even though they won't actually be used.

Is this just bad design or is there a valid reason for this behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橪书 2024-10-01 08:41:26

我以前也遇到过这个问题。这是有正当理由的,但我不记得细节了。

我不记得这是否有效,但您可以尝试在构造函数中声明属性,其中 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

编辑

我刚刚尝试了前面的代码,它的效果符合我的预期。我之前的代码没有编译,因为我错过了构造函数属性,所以我已经修复了这个问题。

I have had this problem before. There was a valid reason for this but I cannot remember the details.

I cannot remember if this works but you can try declaring the property in the constructor where null is the default value.

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; }
    }
}

This is related to using default values and validators but is where a default value is wanted.
http://msdn.microsoft.com/en-us/library/system.configuration.configurationproperty(VS.85).aspx#1

EDIT

I have just tried out the previous code and it does as I expected. My previous code did not compile as I missed out a constructor property so I have fixed that.

蒲公英的约定 2024-10-01 08:41:26

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

但是,DefaultValue 确实适用于这种情况,就像从 XML 反序列化属性时一样(任何 ConfigurationValidatorAttribute 也是如此)。

如果您在单元测试中使用配置部分,这是有意义的。 A)在构造该部分时具有声明性默认值并且 B)验证默认值,这真的很好。

The reason is that the configuration section classes can be newed up in code without there being a configuration file. You can use a default constructor and not specify any values for the property. In this case, even if you have specified IsRequired=true there is no exception thrown. In other words, IsRequired only applies if the property is being deserialized from XML.

However, DefaultValue does apply in this case, as it does when the property is being deserialized from XML (as does any ConfigurationValidatorAttribute).

This makes sense if you are using configuration sections in unit testing. It's really nice to A) have a declarative default value when constructing the section and B) have the default value validated.

那一片橙海, 2024-10-01 08:41:26

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

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

As per my understanding, this behavior is highly required.

Since the configuration is one of the core area of any application, and suppose, no value has been provided for an application critical property, then the whole application may lead to some unwanted behavior(could be a crash, indefinite resource utilization etc). I think that is the reason, most of the .Net inbuilt configuration properties like Session timeout etc. were set to a default value and they will be applied even user didn't specified value.

仲春光 2024-10-01 08:41:26

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

As said previously, this does not help in getting a validation without having to specify a default value for a property, which then makes the IsRequired property of the ConfigurationPropertyAttribute useless.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文