ConfigurationSection - StringValidator failing

2019-05-23 05:56发布

问题:

I want to store three values in my ASP.NET web.config file in a custom element, so this is my web.config:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="mySection" type="Foobar.MySection,Foobar" />
    </configSections>

    <mySection baseUri="https://blargh" sid="123" key="abc" />

    <!-- etc, including <system.web> configuration -->
</configuration>

This is my Configuration code:

namespace Foobar {

public class MySection : ConfigurationSection {

    public MySection () {
    }

    [ConfigurationProperty("baseUri", IsRequired=true)]
    [StringValidator(MinLength=1)]
    public String BaseUri {
        get { return (String)this["baseUri"]; }
        set { this["baseUri"] = value; }
    }

    [ConfigurationProperty("sid", IsRequired=true)]
    [StringValidator(MinLength=1)]
    public String Sid {
        get { return (String)this["sid"]; }
        set { this["sid"] = value; }
    }

    [ConfigurationProperty("key", IsRequired=true)]
    [StringValidator(MinLength=1)]
    public String Key {
        get { return (String)this["key"]; }
        set { this["key"] = value; }
    }
}
}

And I load it using this code:

MySection section = ConfigurationManager.GetSection("mySection") as MySection;
String x = section.BaseUri;

However when I run my code in ASP.NET I get this exception:

[ArgumentException: The string must be at least 1 characters long.]
System.Configuration.StringValidator.Validate(Object value) +679298
System.Configuration.ConfigurationProperty.Validate(Object value) +41

[ConfigurationErrorsException: The value for the property 'baseUri' is not valid. The error is: The string must be at least 1 characters long.]
System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line) +278
System.Configuration.BaseConfigurationRecord.CreateSectionDefault(String configKey, Boolean getRuntimeObject, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object& result, Object& resultRuntimeObject) +59
System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) +1431
System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission) +56
System.Configuration.BaseConfigurationRecord.GetSection(String configKey) +8
System.Web.HttpContext.GetSection(String sectionName) +47
System.Web.Configuration.HttpConfigurationSystem.GetSection(String sectionName) +39
System.Web.Configuration.HttpConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String configKey) +6
System.Configuration.ConfigurationManager.GetSection(String sectionName) +78
<my code that calls GetSection>

Why would the StringValidator be failing when the correctly-formatted value is set in my web.config? What am I overlooking?

回答1:

Because StringValidator is the cause of the exceptions I did some googling and apparently it's a bug in the .NET Framework: having a StringValidator with a Minimum Length argument means that it will always reject the empty string "" default value of the property, which would be set by the framework.

There are workarounds, but I couldn't justify spending time on them, so I stripped out the StringValidator attributes and my code works fine now.

Here's the QA I found: Why does StringValidator always fail for custom configuration section?



回答2:

it clearly states that

The value for the property 'baseUri' is not valid

I think it should be

<mySection baseUri="https://blargh"  sid="123" key="abc" />


回答3:

The StringValidator is the root problem, it could be resolved by any one of:

  • Removing MinLength argument
  • Setting MinLength = 0
  • removing StringValidator Attribute
  • adding DefaultValue to the ConfigurationProperty Attribute

The Ideal definition for the property is like:

    [ConfigurationProperty("title", IsRequired = true, DefaultValue = "something")]
    [StringValidator(InvalidCharacters = "~!@#$%^&*()[]{}/;’\"|\\"
      , MinLength = 1
      , MaxLength = 256)]
    public string Title
    {
        get { return this["title"] as string; }
        set { this["title"] = value; }
    }