ASP.NET RangeValidator weirdness with MaximumValue

Julian picture Julian · Mar 23, 2011 · Viewed 19.6k times · Source

I have a pretty simple ASP.NET page with some input fields and validators. One field accepting a double looks like this:

<asp:TextBox ID="tbHeight" runat="server" />
<asp:RangeValidator ID="vdHeight" runat="server" 
    ErrorMessage="Height must be a positive number" Text="*" 
    ControlToValidate="tbHeight" MinimumValue="0" Type="Double" />

This works as expected, and the user must enter a number >= 0.
Update: this does not work as expected afterall (some weird bug in the project). See comments to the answers below for details

I then try the same for a field accepting an integer:

<asp:TextBox ID="tbGrossTonnage" runat="server" />
<asp:RangeValidator ID="vdGrossTonnage" runat="server" 
    ErrorMessage="Gross Tonnage must be a positive whole number" Text="*" 
    ControlToValidate="tbGrossTonnage" MinimumValue="0" Type="Integer" />

When loading the ASP-page, this gives me the following error: The value '' of the MaximumValue property of 'vdGrossTonnage' cannot be converted to type 'Integer'.

I don't have any specific max value requirements in the system, so I would just like it to "default" to Int32.MaxValue (although I'd have to enter 2,147,483,647, since MaximumValue doesn't seem to accept the Int32.MaxValue constant).

Why is it that a RangeValidator of the type Integer won't accept a missing MaximumValue property, but for one of the type Double this is ok?

Answer

Chris W. Rea picture Chris W. Rea · Mar 23, 2011

The MinimumValue and MaximumValue properties of the RangeValidator class return string.Empty as their default when not set.

Next, it also happens that the Convert() protected method implemented by BaseCompareValidator, which is used for converting the string properties to values, calls int.Parse() for the ValidationDataType.Integer case. int.Parse() doesn't like the empty string and will throw an exception.

But, in the case of ValidationDataType.Double, Convert() first calls another protected method, ConvertDouble() (instead of double.Parse()), and in that method it explicitly returns a string value of "0" when an empty string is detected, and that string value "0" later parses, via double.Parse() into 0d.

The integer case doesn't benefit from such a mapping of string.Empty to "0".

Hence, the dicrepancy. The devil is in the details, and Reflector is your friend.