CompareValidator does not allow thousands separator - is this a bug or by design?

386 views Asked by At

Minimal, Complete, and Verifiable example (Framework 3.5):

<%@ Page Language="C#" Culture="en-US" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
    <form id="form1" runat="server">
        <asp:TextBox ID="txt" runat="server" />
        <asp:CompareValidator runat="server" ControlToValidate="txt" Operator="DataTypeCheck" Type="Double" Text="This is not a double." />
        <asp:Button runat="server" Text="Do Postback" />
    </form>
</body>
</html>

Enter 1,234.0 in the text box and hit TAB.

Expected result: Nothing.
Actual result: This is not a double.

Why do I expect the comparison to succeed: Because the documentation says: "Validation fails if the value cannot be converted to the specified data type.", but Convert.ToDouble("1,234.0", CultureInfo.GetCultureInfo("en-US")) succeeds.

My question:

Is this a bug (which I should report to Microsoft Connect) or did I miss some part of the documentation where it says that CompareValidator uses different conversion rules than the remainder of the .NET framework?

2

There are 2 answers

1
Azhar On

Rather than using Type="Double", try using Type="Currency". It should accept values with and without commas, however it will not accept more than 2 decimal places.

0
Heinzi On

Is this a bug (which I should report to Microsoft Connect) or did I miss some part of the documentation where it says that CompareValidator uses different conversion rules than the remainder of the .NET framework?

Neither. I assume that this is a deliberate, but underdocumented feature.

Why do I assume that? Because of the reference source of BaseCompareValidator.Convert: Type="Integer" validations are performed by simply trying Int32.Parse, but double validations explicitly match against some regular expression, which includes the decimal separator but not the thousands separator. Something similar is done for validating decimals (but including the thousands separator, or, more precisely, the "group separator"). So, it's apparently not an oversight (since they explicitly allowed the thousands separator for currency values).

Why did they do all that extra work instead of just checking for the result of double.TryParse? I can only speculate, by the following reasons would make sense:

  • CompareValidator has been around since .NET 1, but, if I recall correctly, TryParse was added only later. Maybe they wanted to avoid the overhead of calling Parse and catching the exception.

  • For a developer, it's obvious that 1e10 and NaN are valid doubles, but not to most end-users. Thus, it makes sense to exclude them.

That still does not explain why they deliberately avoided the thousands separator, but, from the limited information available, this is the best I could get...