代码之家  ›  专栏  ›  技术社区  ›  Costin

firefox上的Comparevalidator问题

  •  4
  • Costin  · 技术社区  · 14 年前

    我需要在Web表单应用程序中验证日期。为此,我使用了一个比较器

    Operator="DataTypeCheck" Type="Date"
    

    问题是这个验证器在2位数年份的火狐上不能正常工作。(javascript错误: m[2]未定义 ) 它的年份是4位数,工作正常。

    这里也描述了这个问题: https://connect.microsoft.com/VisualStudio/feedback/details/355573/comparevalidator-client-side-bug-two-digit-year-in-mozilla-based-browsers-throws-js-exception

    有人知道一个很好的解决方法吗?

    谢谢

    4 回复  |  直到 10 年前
        1
  •  2
  •   Michael Liu    10 年前

    这是ASP.NET 3.5及更早版本的客户端验证脚本中的错误。(该脚本在旧版本的Internet Explorer中正常工作,但在新的符合标准的浏览器中无法正常工作。)

    Microsoft已修复了ASP.NET 4.0中的错误。

    如果无法升级到ASP.NET 4.0,则可以从.NET 4.0附带的system.web.dll版本中导出webuivalidation.js资源,然后在页面的 PreRender 事件:

    this.ClientScript.RegisterClientScriptInclude(
        typeof(System.Web.UI.WebControls.BaseValidator), "WebUIValidation.js",
        "url-to-the-4.0-WebUIValidation.js-script");
    

    或者,您也可以覆盖马车 ValidatorConvert 通过将以下内容添加到 <script type="text/javascript"> 在页面上阻止:

    function ValidatorConvert(op, dataType, val) {
        function GetFullYear(year) {
            var twoDigitCutoffYear = val.cutoffyear % 100;
            var cutoffYearCentury = val.cutoffyear - twoDigitCutoffYear;
            return ((year > twoDigitCutoffYear) ? (cutoffYearCentury - 100 + year) : (cutoffYearCentury + year));
        }
        var num, cleanInput, m, exp;
        if (dataType == "Integer") {
            exp = /^\s*[-\+]?\d+\s*$/;
            if (op.match(exp) == null)
                return null;
            num = parseInt(op, 10);
            return (isNaN(num) ? null : num);
        }
        else if(dataType == "Double") {
            exp = new RegExp("^\\s*([-\\+])?(\\d*)\\" + val.decimalchar + "?(\\d*)\\s*$");
            m = op.match(exp);
            if (m == null)
                return null;
            if (m[2].length == 0 && m[3].length == 0)
                return null;
            cleanInput = (m[1] != null ? m[1] : "") + (m[2].length>0 ? m[2] : "0") + (m[3].length>0 ? "." + m[3] : "");
            num = parseFloat(cleanInput);
            return (isNaN(num) ? null : num);
        }
        else if (dataType == "Currency") {
            var hasDigits = (val.digits > 0);
            var beginGroupSize, subsequentGroupSize;
            var groupSizeNum = parseInt(val.groupsize, 10);
            if (!isNaN(groupSizeNum) && groupSizeNum > 0) {
                beginGroupSize = "{1," + groupSizeNum + "}";
                subsequentGroupSize = "{" + groupSizeNum + "}";
            }
            else {
                beginGroupSize = subsequentGroupSize = "+";
            }
            exp = new RegExp("^\\s*([-\\+])?((\\d" + beginGroupSize + "(\\" + val.groupchar + "\\d" + subsequentGroupSize + ")+)|\\d*)"
                            + (hasDigits ? "\\" + val.decimalchar + "?(\\d{0," + val.digits + "})" : "")
                            + "\\s*$");
            m = op.match(exp);
            if (m == null)
                return null;
            if (m[2].length == 0 && hasDigits && m[5].length == 0)
                return null;
            cleanInput = (m[1] != null ? m[1] : "") + m[2].replace(new RegExp("(\\" + val.groupchar + ")", "g"), "") + ((hasDigits && m[5].length > 0) ? "." + m[5] : "");
            num = parseFloat(cleanInput);
            return (isNaN(num) ? null : num);
        }
        else if (dataType == "Date") {
            var yearFirstExp = new RegExp("^\\s*((\\d{4})|(\\d{2}))([-/]|\\. ?)(\\d{1,2})\\4(\\d{1,2})\\.?\\s*$");
            m = op.match(yearFirstExp);
            var day, month, year;
            if (m != null && (((typeof(m[2]) != "undefined") && (m[2].length == 4)) || val.dateorder == "ymd")) {
                day = m[6];
                month = m[5];
                year = (m[2].length == 4) ? m[2] : GetFullYear(parseInt(m[3], 10));
            }
            else {
                if (val.dateorder == "ymd"){
                    return null;
                }
                var yearLastExp = new RegExp("^\\s*(\\d{1,2})([-/]|\\. ?)(\\d{1,2})(?:\\s|\\2)((\\d{4})|(\\d{2}))(?:\\s\u0433\\.|\\.)?\\s*$");
                m = op.match(yearLastExp);
                if (m == null) {
                    return null;
                }
                if (val.dateorder == "mdy") {
                    day = m[3];
                    month = m[1];
                }
                else {
                    day = m[1];
                    month = m[3];
                }
                year = ((typeof(m[5]) != "undefined") && (m[5].length == 4)) ? m[5] : GetFullYear(parseInt(m[6], 10));
            }
            month -= 1;
            var date = new Date(year, month, day);
            if (year < 100) {
                date.setFullYear(year);
            }
            return (typeof(date) == "object" && year == date.getFullYear() && month == date.getMonth() && day == date.getDate()) ? date.valueOf() : null;
        }
        else {
            return op.toString();
        }
    }
    
        2
  •  1
  •   Tim Schmelter    14 年前

    也许这对您有帮助(最后一篇文章,只需要datatype==“date”就行了),但我还没有测试过它: http://forums.asp.net/t/1358621.aspx

        3
  •  0
  •   Costin    14 年前

    我的解决方案是创建一个继承自 BaseValidator 并覆盖 ControlPropertiesValid(), EvaluateIsValid() and OnPreRender(EventArgs e) . 如果你有其他想法,请开枪。

        4
  •  0
  •   pghcpa    10 年前

    使用自定义验证器

    Imports System.Globalization
    
      Private Sub CustomValidator1_ServerValidate(source As Object, args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
        Dim dateResult As Date
        If Date.TryParse(TextBox1.Text, CultureInfo.CreateSpecificCulture("zh-CN"), DateTimeStyles.None, dateResult) Then
            args.IsValid = True
        Else
            args.IsValid = False
        End If
    End Sub
    

    如果愿意的话,可以在JS的客户端使用等效的。