ASP.NET RangeValidator具有最大值的古怪特性

ASP.NET RangeValidator具有最大值的古怪特性,asp.net,validation,rangevalidator,Asp.net,Validation,Rangevalidator,我有一个非常简单的ASP.NET页面,其中包含一些输入字段和验证器。一个接受双精度的字段如下所示: <asp:TextBox ID="tbHeight" runat="server" /> <asp:RangeValidator ID="vdHeight" runat="server" ErrorMessage="Height must be a positive number" Text="*" ControlToValidate="tbHeight" M

我有一个非常简单的ASP.NET页面,其中包含一些输入字段和验证器。一个接受双精度的字段如下所示:

<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" />

这与预期的一样,用户必须输入一个大于等于0的数字。
更新:这并没有达到预期的效果(项目中有一些奇怪的bug)。有关详细信息,请参阅下面答案的注释

然后,我尝试对接受整数的字段执行相同的操作:

<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" />

加载ASP页时,这会导致以下错误:“VDGrosstonage”的MaximumValue属性的值“”无法转换为类型“Integer”

我在系统中没有任何特定的最大值要求,所以我只希望它“默认”为
Int32.MaxValue
(尽管我必须输入2147483647,因为
MaximumValue
似乎不接受
Int32.MaxValue
常量)


为什么类型为
Integer
RangeValidator
不接受缺少的
MaximumValue
属性,但是对于其中一种类型的
Double
,这可以吗?

最好为
RangeValidator
指定
MaximumValue
,即使您的要求没有特别要求。在这种情况下,只需对
类型使用
MaxValue
MaximumValue
的默认值是
String.Empty

未设置时,
RangeValidator
类返回
String.Empty
MinimumValue
MaximumValue
属性作为默认值

接下来,由
BaseCompareValidator
实现的
Convert()
受保护方法(用于将字符串属性转换为值)调用
int.Parse()
,用于
ValidationDataType.Integer
案例
int.Parse()
不喜欢空字符串,将引发异常

但是,在
ValidationDataType.Double
的情况下,
Convert()
首先调用另一个受保护的方法,
ConvertDouble()
(而不是
Double.Parse()
),在该方法中,当检测到空字符串时,它显式返回一个字符串值“0”,然后解析该字符串值“0”,通过
double.Parse()
进入
0d

整数大小写不能从
string.Empty
到“0”的映射中获益


因此,双份性。魔鬼在细节中,它是你的朋友。

在Type=“Double”上将MaximumValue留空相当于将MaximumValue设置为0。我不确定你对第一个例子的理解是否正确。只是为了让它更加混乱

在我的formview中(如果有什么不同的话,它位于updatepanel中),我有


纬度:
经度:
注意,我的纬度和经度验证基本相同,只是经度允许更高的最大值

运行时,经度完全按照预期进行验证-类型必须是数字,值必须介于0和180之间


纬度类型必须为数字,如果值为负,则范围失败,但未检查maxvalue。我可以在文本框中输入数以百万计的值,验证不会失败。

只是一个小的跟进:如果我在双精度类型中省略了
MaximumValue
,那么这就意味着最小值和最大值都是0。那么,为什么我的页面正确验证了字段(-1无效,1有效(我已仔细检查,这确实有效))?@Nailuj我无法证实您的发现,即页面以“1”作为输入正确验证。如果我将你的控件(从上面的第一个代码片段)放到一个空网站项目的新页面上,输入“1”,然后导致回发(我添加了一个按钮)确实会导致验证失败。另外需要注意的是,它似乎对日期字段执行字符串比较,而不是日期比较,因此将接受2016年12月1日的范围验证器不会接受“2016年12月1日”是的,我确信我的第一个示例工作正常。我已经仔细检查过了(见我对Chris W.Rea回答的评论)。@Nailuj我试过你的例子,但效果不好。(见我上面的评论)你能像我一样,在你的应用程序之外,在一个新的网站项目中,以尽可能简单的方式再试一次吗?也许您的应用程序中还有其他代码。e、 g.您是否有选择地启用/禁用任何验证器?等等@Chris W.Rea:我尝试了一个新的ASP.NET项目,在这种情况下,我得到了与您相同的结果:验证无法正常工作。我想不出在我的其他应用程序中有什么明显的原因会导致这种情况。。。但这并不重要,我将确保显式地指定最小值和最大值。谢谢你花时间来测试:)@Nailuj如果是我,我会想弄清楚到底发生了什么。尝试一个接一个地删除你的“令人费解的工作良好”页面的部分(然后重新测试),直到你把它减少到验证开始失败的程度。。。那么,你移走的最后一件东西可能就是罪魁祸首。如果不这样做,可能会留下一个bug供同事稍后查找;-)@克里斯·W·雷亚:是的,那确实是一件负责任的事情。在一个完美的世界里,我也非常愿意这样做。然而,这个项目太大了,意大利面太多了,根本不可行。这样说有点伤人,但由于时间和资源有限,有时人们不得不面对这样的现实:-/
<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>