Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does ConfigurationValidator validate the default value of a ConfigurationProperty even if IsRequired is 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?

like image 971
hwiechers Avatar asked Sep 19 '10 07:09

hwiechers


2 Answers

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.

like image 190
Bronumski Avatar answered Nov 20 '22 16:11

Bronumski


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.

like image 27
Michiel van Oosterhout Avatar answered Nov 20 '22 17:11

Michiel van Oosterhout