asp:CustomValidator / OnServerValidate

时间:2010-03-23 14:24:38

标签: asp.net validation checkboxlist customvalidator

我有一个CheckBoxList,我试图验证至少有一个复选框被选中。

标记:

<asp:CustomValidator ID="RequiredFieldValidator8" ValidationGroup="EditArticle"
    runat="server" ErrorMessage="At least one Category is required."
    OnServerValidate="topic_ServerValidate" />
<asp:CheckBoxList id="checkboxlistCategories" runat="server"></asp:CheckBoxList>

代码隐藏:

protected void topic_ServerValidate(object source, ServerValidateEventArgs args)
{
    int i = 0;
    foreach (ListItem item in checkboxlistCategories.Items)
    {
        if (item.Selected == true)
            i = i + 1;
    }
    if (i == 0)
        args.IsValid = false;
    else
        args.IsValid = true;
}

如果我在CustomValidator控件中添加ControlToValidate =“checkboxlistCategories”,它会爆炸!我得到的例外是:

  

System.Web.HttpException:由'RequiredFieldValidator8'的ControlToValidate属性引用的控件'checkboxlistCategories'

我错过了什么吗?

5 个答案:

答案 0 :(得分:1)

这是一个更简洁的 jQuery 实现,它允许一个 ClientValidationFunction 用于页面上任意数量的 CheckBoxList 控件:

function ValidateCheckBoxList(sender, args) {
 args.IsValid = false;

 $("#" + sender.id).parent().find("table[id$="+sender.ControlId+"]").find(":checkbox").each(function () {
     if ($(this).attr("checked")) {
  args.IsValid = true;
  return;
     }
 });
}

这是标记:

<asp:CheckBoxList runat="server"
    Id="cblOptions" 
    DataTextField="Text" 
    DataValueField="Id" />

<xx:CustomValidator Display="Dynamic" 
        runat="server" 
        ID="cblOptionsValidator"
        ControlId="cblOptions"
        ClientValidationFunction="ValidateCheckBoxList" 
        ErrorMessage="One selection required." />

最后,自定义验证器允许客户端函数通过ID检索目标控件:

public class CustomValidator : System.Web.UI.WebControls.CustomValidator
{
 public string ControlId { get; set; }

 protected override void OnLoad(EventArgs e)
 {
     if (Enabled)
         Page.ClientScript.RegisterExpandoAttribute(ClientID, "ControlId", ControlId);

     base.OnLoad(e);
 }
}

答案 1 :(得分:0)

考虑到您的服务器端验证方法topic_ServerValidate特定于checkboxlistCategories字段,您无需设置ControlToValidate属性。

添加ControlToValidate属性时它“爆炸”的原因是您引用的控件的类型 - CheckBoxList。在为任何类型的验证器分配ControlToValidate时,该验证器将在执行实际验证逻辑之前自动对引用的控件执行“非空”检查。如果该字段为空,则不进行验证(即验证成功)。当然,除非你设置ValidateWhenEmpty = true。显然,验证器不知道如何检查CheckBoxList是否为空,而是抛出异常。

在您的特定情况下,CustomValidator实际上只用作非空检查,即使引用的控件保持“空”,您也肯定希望验证器发生。正如我的答案的第一段所述,实现这一目标的最简单方法是删除违规和不必要的财产。

答案 2 :(得分:0)

只是一个建议,但您可以使用单选按钮来定义组名。这将消除验证b / c的需要,只能在组内检查一个单选按钮。

答案 3 :(得分:0)

也许我错过了什么。但是CheckBoxList控件没有ValidationPropertyAttribute。因此,您不能将其用作ControlToValidate属性。试试这个:

<强> CheckBoxList.cs

[ValidationProperty("SelectedIndex")]
public class CheckBoxList : System.Web.UI.WebControls.CheckBoxList
{
}

<强>的Web.Config

<tagMapping>
  <add tagType="System.Web.UI.WebControls.CheckBoxList, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" mappedTagType="Namespace.CheckBoxList, Assembly"/>
</tagMapping>

无论如何,斯科特·米切尔写了一篇很棒的文章here

答案 4 :(得分:0)

正如迈赫迪所提到的那样,4个家伙在他回答的链接中提到了这一点。

为简洁起见,这是代码清单 -

public class CheckBoxListRequiredFieldValidator : BaseValidator
{
    private ListControl _listctrl;

    public CheckBoxListRequiredFieldValidator()
    {
        base.EnableClientScript = false;
    }

    protected override bool ControlPropertiesValid()
    {
        Control ctrl = FindControl(ControlToValidate);

        if (ctrl != null)
        {
            _listctrl = (ListControl)ctrl;
            return (_listctrl != null);
        }
        else
            return false;  
    }

    protected override bool EvaluateIsValid()
    {
        return _listctrl.SelectedIndex != -1;
    }
}

将此獾弹出到您的用户控件库中,然后离开。

HTH。