Sean Gough Sean Gough - 3 months ago 22
ASP.NET (C#) Question

Why does StringValidator always fail for custom configuration section?

I have created a custom configuration section in a c# class library by inheriting from

ConfigurationSection
. I reference the class library in my web application (also c#, ASP.NET), fill in the appropriate attributes and everything works great. The problem starts when I start adding validators.

For example, this property:

[ConfigurationProperty("appCode", IsRequired = true)]
public string ApplicationCode
{
get
{
return (string)base["appCode"];
}
set
{
base["appCode"] = value;
}
}


As is it works fine, but as soon as I add this:

[StringValidator(MinLength=1)]


It bombs with the following error:

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

I get this error even though a valid
appCode
value is in my
web.config
file. If I remove the validator it works perfectly. Does anyone know how to get around this?

Answer

I was able to work around this issue by using an explicit ConfigurationProperty as the key to my properties collection rather than a string, as per the following implementation:

public class AssemblyElement : ConfigurationElement
{
    private static readonly ConfigurationProperty _propAssembly;
    private static readonly ConfigurationPropertyCollection _properties;

    static AssemblyElement()
    {
        _propAssembly = new ConfigurationProperty("assembly", typeof(string), null, null, new StringValidator(1), ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired);
        _properties = new ConfigurationPropertyCollection();
        _properties.Add(_propAssembly);
    }

    internal AssemblyElement() { }
    public AssemblyElement(string assemblyName)
    {
        this.Assembly = assemblyName;
    }

    [ConfigurationProperty("assembly", IsRequired = true, IsKey = true, DefaultValue = "")]
    [StringValidator(MinLength = 1)]
    public string Assembly
    {
        get { return (string)base[_propAssembly]; }
        set { base[_propAssembly] = value; }
    }

    internal AssemblyName AssemblyName
    {
        get { return new AssemblyName(this.Assembly); }
    }

    protected override ConfigurationPropertyCollection Properties
    {
        get { return _properties; }
    }
}

(This code is closely modeled after the code reflected from the AssemblyInfo configuration element class. I still wish I didn't have to duplicate my validations, but at least this code allows me to specify a blank default value while still requiring a value to be entered.)

Comments