【问题标题】:How to client side validate a custom control?如何客户端验证自定义控件?
【发布时间】:2012-05-19 08:59:14
【问题描述】:

跟进我的previous question 关于自定义控件和验证我现在可以进行服务器端验证,但似乎无法弄清楚如何添加客户端验证。我必须遵循控制:

[ValidationProperty("Text")]
[ToolboxData("<{0}:DateSelect runat=server></{0}:DateSelect>")]
public class DateSelect : System.Web.UI.WebControls.Panel
{
 private DropDownList day;
 private DropDownList month;
 private DropDownList year;

 public DateSelect()
 {
    day = new DropDownList();
    /* some code to create items for 'day' here */
    Controls.Add(day);
    month = new DropDownList();
    /* some code to create items for 'month' here */
    Controls.Add(month);
    year = new DropDownList();
    /* some code to create items for 'year' here */
    Controls.Add(year);
 }


 public string Text
 {
    get
    {
        return year.Text + "-" + month.Text + "-" + day.Text;
    }
 }
}

在我的网络表单上添加此控件,在 DataType 操作中添加一个 CompareValidator 以检查有效日期。我将验证器的EnableClientScript 设置为false,并且自定义控件在服务器端得到了很好的验证,并在正确的情况下提供了正确的消息。但是,一旦我将EnableClientScript 转换为true,自定义控件就会在客户端进行验证,并在 DropDownLists 中实际上存在有效日期时生成错误消息。我一直在试图找出原因并最终得到了 .net 生成的以下 javascript,我认为它永远不会产生正确的值:

function ValidatorGetValueRecursive(control)
{
    if (typeof(control.value) == "string" && (control.type != "radio" || control.checked == true)) {
        return control.value;
    }
    var i, val;
    for (i = 0; i<control.childNodes.length; i++) {
        val = ValidatorGetValueRecursive(control.childNodes[i]);
        if (val != "") return val;
    }
    return "";
}

所以我相信我必须在我的自定义控件中添加一些东西,也许是一段 javascript,一旦验证器尝试验证我的控件并生成正确的值以从三个中的选定项中进行验证,它就会被调用下拉列表。我只是不知道在哪里添加这个脚本。有什么指点吗?

【问题讨论】:

    标签: c# asp.net validation client-side


    【解决方案1】:

    因为您的控件实际上包含多个服务器控件,所以我建议将客户端验证器添加到控件集合中,就像您对其他控件所做的那样。

    var ddl = new DropDownList();
    ddl.ID = "ddlDay";
    Controls.Add(ddl);
    
    var validator = new RequiredFieldValidator();
    val.ControlToValidate = ddl.ID;
    val.ErrorMessage = "*"; //property to set this for all validators
    val.Display = ValidatorDisplay.Dynamic; //property to set this for all validators
    Controls.Add(validator);
    

    添加验证器后,您可以公开属性以应用于控件中的所有验证器,如验证组、错误消息、显示类型等。

    编辑#1

    如果您想将组合输入验证为一个,请使用CustomValidator 并通过控件注册必要的客户端脚本。

    我根本没有测试过这个,但下面是一个简单的代码示例来演示这个概念。显然,您可以使用 StringBuilder 或其他东西在代码中构建验证函数:

    <script type="text/javascript">
        clientValidate = function(source, args){
    
            var ddl1 = document.getElementById("<%= ddl1.ClientID %>");
            var ddl2 = document.getElementById("<%= ddl2.ClientID %>");
    
            if (ddl1.options[e.selectedIndex].value.length == 0)
                args.IsValid = false;
            if (ddl2.options[e.selectedIndex].value.length == 0)
                args.IsValid = false; 
    
        }
    </script>
    <asp:CustomValidator ID="MyCustomValidator" runat="server"
        ErrorMessage="Invalid" 
        ClientValidationFunction="clientValidate" />
    

    这里有一些文章解释了如何使用自定义验证器进行客户端验证:

    编辑#2

    更多阅读表明CustomValidator 应该与您的复合控件兼容。

    【讨论】:

    • 好的,我明白你在说什么,但这如何使客户端验证器根据 3 个 DropDownList 的选定项目的组合作为日期进行验证?另请注意,在我当前的设置中,服务器端验证工作正常。
    • 如果组合输入是您要验证的内容,我会使用CustomValidator,并让您的控件插入必要的客户端脚本来执行验证。
    • 我理解您的观点,但更喜欢从另一种方式解决问题,即以 CompareValidator 与它一起使用的方式调整自定义控件。这样做的原因是所有控件和验证器都是根据数据库期望的字段和数据类型动态创建的。我认为您的解决方案是可行的,但由于 CompareValidator 在服务器端工作,我觉得应该可以让它在客户端工作。我只是不知道在哪里挂钩。
    • @Bazzz:将ControlToValidate 属性设置为自定义控件的ID 不起作用?当你这样做时会发生什么?
    • @Bazzz:另外,请参阅我的回答中的 Edit #2。我认为CustomValidator 可以很好地与您的自定义控件配合使用,并且它足够灵活,可以处理任何类型的验证,即必填字段、比较、正则表达式等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 2011-02-21
    相关资源
    最近更新 更多