Thursday, May 15, 2008

Finicky Configuration.RegexStringValidator

I was working on a custom ConfigurationElement for an HttpModule and I needed two properties. They both needed to be in the form of a URL (but only the host) and one was required. Regular expressions are a great tool for easily verifying a string is in a certain format and Microsoft was nice enough to include the RegexStringValidatorAttribute. So I tried this:

[ConfigurationProperty("Url", IsRequired = true)]
[RegexStringValidator(@"^https?://[A-Za-z\d\-_\.]+$")]

[ConfigurationProperty("Url2", IsRequired = false)]
[RegexStringValidator(@"^https?://[A-Za-z\d\-_\.]+$")]

If you know regular expressions you can see a simple URL like "http://www.jessemandel.com" should validate. Neither one worked, plus it gave me the misleading error that "http://www.jessemandel.com" wasn't validating.

After a bit of fiddling around, I figured out that at some point the RegexStringValidator is validating the default value. In this case it's an empty string which is not valid. This makes sense for Url2 if it's not provided but it told me "http://www.jessemandel.com" was invalid.

The second one was an easy fix. Since it's not required, I changed the regular expression to allow "" and now it works.

[ConfigurationProperty("Url2", IsRequired = false)]
[RegexStringValidator(@"^(https?://[A-Za-z\d\-_\.]+)?$")]

I can't do the same for the first one because I don't want an empty string to be valid. It's required so it's never empty but I guess when it initializes it loads the default value. Adding a DefaultValue that is valid does the trick.

[ConfigurationProperty("Url", IsRequired = true, DefaultValue = "http://localhost")]
[RegexStringValidator(@"^https?://[A-Za-z\d\-_\.]+$")]

You don't have to worry about the DefaultValue much because if you do not include the property at all you'll get the error, "Required attribute 'Url' not found." and if you include an invalid Url, you'll get the error, "The value does not conform to the validation regex string '^https?://[A-Za-z\d\-_\.]+$'."

1 comment:

Zeuson said...

You saved my day!