Using RegexValidator for int/decimal types

Topics: Validation Application Block
Mar 2, 2007 at 6:15 PM
Edited Mar 2, 2007 at 6:50 PM
I have the following code:

/* 2 digit integer format */
RegexValidator("^\\d{0,2}$", Tag="Integer Range", MessageTemplate="Integer is out of range 2 XX")
public int myInt{...}

/* 7,2 decimal format */
public decimal MyDecimal{...}

The above code does not work. I am getting the following error message:

Value to validate is not of the expected type: expected System.String

Does the Regex validator only work with string types?

In previous CTPs there was an IntValidator. It seems to be missing in the February CTP. Has it been replaced by something else?
Mar 2, 2007 at 6:29 PM
Correct, the RegExValidator only works on strings. In this instance you should be using the RangeValidator. We got rid of the Int32RangeValidator, since the new RangeValidator works on any IComparable type.

Mar 2, 2007 at 6:46 PM
Edited Mar 2, 2007 at 6:46 PM
Ok, I see that the Int32Validator has been replaced by the RangeValidator. And it was recommended to use the RangeValidator for decimal types as well.

In that case, how would I would Validate a decimal value is in the correct format.

E.g. 7,2 (7-digits in total, 2 after of them after the decimal place - #####.##)

The Regular expression in the above post does this for me, so I was expecting that to work. And the type of validation I'm doing is not related to range.
Mar 2, 2007 at 7:02 PM
Besides validating format, another issue is how to set the correct range for a decimal. I only see integer bounds for the RangeValidator. How to test if a decimal is between 2.35 and 2.76 for example?
Mar 2, 2007 at 7:19 PM
I just discovered the exact same issue. This is a bug with the RangeValidatorAttribute which we'll need to look at. A simple fix for most cases is to change the constructor accepting objects for bounds from internal to public.

However I also discovered an even nastier issue. For some reason I don't comprehend, C# does not let you pass decimals to attributes, even if you use the literal syntax of 0.0M (link). So this will require a more complex fix - it will probably be necessary to pass the bounds in as strings, and we'll convert them to decimals inside the class.

Sorry about the issue, and thanks for reporting it.

Mar 5, 2007 at 6:35 PM
We've updated the RangeValidatorAttribute class to fix the issue. There are now additional overloads to support different primitive types for the boundaries. In addition if you want to use any non-attribute-friendly types (including Decimal) you can now specify them as strings and tell the attribute which type to convert them to, for example:
[RangeValidator(typeof(Decimal), "0.0", RangeBoundaryType.Exclusive, "1000.0", RangeBoundaryType.Inclusive, MessageTemplate="Withdrawal amount must be between zero and 1000.")]
Rather than make you wait for the final release, I posted the updated RangeValidatorAttribute.cs file to this site. Let me know if you have any further issues with this feature.

Mar 5, 2007 at 8:11 PM
Is there any chance of implementing numeric formating validation with the RegexValidator? For instance, provide an option to use RegexValidator to validate the string representation of an object (int, decimal, double, etc). I can see this being popular - not that I am wanting it myself. ;)
Mar 5, 2007 at 8:32 PM
Edited Mar 5, 2007 at 9:23 PM
Hi Greif -

I commented on this in the issue tracker tool. I don't think this is a good idea since there is no one standard way of representing a numeric value as a string. For example 1234.567 may also be validly represented as "1,234.567" or "1.234,567" depending on culture settings, and this would impact the results of the regex match.

You can apply a validation rule to a property or parameterless method, so you could do something like:
    public int SomeValue 
        get { return someValue; }
        set { someValue = value; }
    public string SomeValueAsString
        get { return someValue.ToString(/*format or culture stuff*/); }

Will this work for you?
Mar 6, 2007 at 3:38 PM
Sorry, the light bulb clicked and I understand the problem now.

On a side note, any inside plans for generic attributes to be supported in C#?
Mar 12, 2007 at 9:19 PM
I tried the updated RangeValidatorAttribute.cs file posted above, but cannot get it to compile. I receive two errors:

'Microsoft.Practices.EnterpriseLibrary.Validation.Properties.Resources' does not contain a definition for 'ExceptionBoundTypeNotIComparable'
Line 157
'Microsoft.Practices.EnterpriseLibrary.Validation.Properties.Resources' does not contain a definition for 'ExceptionCannotConvertBound'
Line 184

Are there additional files we need to include to test out using the generic RangeValidator (as we want to test out validating decimal types)?

Mar 12, 2007 at 9:24 PM
Sorry - looks like we added a couple of resources to Properties\Resources.resx. You can add these yourself - here are the strings we're using:

Name Value
ExceptionBoundTypeNotIComparable The supplied bound type is not compatible with IComparable.
ExceptionCannotConvertBound The string representing the bound value could not be converted to the bound type.

Mar 12, 2007 at 10:08 PM
Thanks, that worked to compile.