问题
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?
回答1:
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.
回答2:
Leaving the MaximumValue blank on Type="Double" is equivalent to setting MaximumValue to 0. I'm not sure you are right about the first of your examples working fine.
回答3:
It is best practice to specify MaximumValue
for the RangeValidator
even if your requirements does not specifically call for one. In that case just use the MaxValue
for the Type
. The default value for MaximumValue
is String.Empty
.
回答4:
Just to make it more confusing..
In my formview (which is in an updatepanel if that makes any difference) I have..
<div class="Width100PercentPadded">
<div class="Width40PercentPadded FloatLeft ClearLeft">
Latitude:
</div>
<div class="Width60PercentPadded FloatLeft">
<asp:TextBox runat="server" ID="txtLatitude" CssClass="Width100Percent" Text='<%# Bind("Latitude") %>' ></asp:TextBox>
<asp:CompareValidator ID="CompareValidatorLatitude" runat="server" ControlToValidate="txtLatitude" Operator="DataTypeCheck" Type="Double" ErrorMessage="Latitude must be numeric" Text="must be numeric" ForeColor="Red" Display="Dynamic"></asp:CompareValidator>
<asp:RangeValidator ID="RangeValidatorLatitude" runat="server" ControlToValidate="txtLatitude" MinimumValue="0" MaximumValue="90" ErrorMessage="Latitude in range 0 to 90" Text="range 0 to 90" ForeColor="Red" Display="Dynamic"></asp:RangeValidator>
</div>
</div>
<div class="Width100PercentPadded">
<div class="Width40PercentPadded FloatLeft ClearLeft">
Longitude:
</div>
<div class="Width60PercentPadded FloatLeft">
<asp:TextBox runat="server" ID="txtLongitude" CssClass="Width100Percent" Text='<%# Bind("Longitude") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidatorLongitude" runat="server" ControlToValidate="txtLongitude" Operator="DataTypeCheck" Type="Double" ErrorMessage="Longitude must be numeric" Text="must be numeric" ForeColor="Red" Display="Dynamic"></asp:CompareValidator>
<asp:RangeValidator ID="RangeValidatorLongitude" runat="server" ControlToValidate="txtLongitude" MinimumValue="0" MaximumValue="180" ErrorMessage="Longitude in range 0 to 180" Text="range 0 to 180" ForeColor="Red" Display="Dynamic"></asp:RangeValidator>
</div>
</div>
Note my latitude and longitude validation is essentially the same except Longitude allows a higher maxvalue.
When running, Longitude is validated exactly as expected - type must be numeric and value must be between 0 and 180.
Latitude type must be numeric, and range fails if value is negative, but the maxvalue is not checked. I can put values in the millions in the textbox and validation does not fail.
来源:https://stackoverflow.com/questions/5406124/asp-net-rangevalidator-weirdness-with-maximumvalue