自定义验证器无法正常工作

9

我有以下一段ASP代码:

<asp:ValidationSummary ID="RegisterUserValidationSummary" runat="server" CssClass="failureNotification" 
        ValidationGroup="RegisterUserValidationGroup"/>

...

<asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserNameTB">Username:</asp:Label>
<asp:TextBox ID="UserNameTB" runat="server" CssClass="textEntry"></asp:TextBox>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" ControlToValidate="UserNameTB" 
      ValidationExpression="[a-zA-Z]{3,8}" ErrorMessage="Username must be between 3 to 8 chars" runat="server"
      CssClass="failureNotification" ToolTip="Username must be between 3 to 8 chars" ValidationGroup="RegisterUserValidationGroup">
    *</asp:RegularExpressionValidator>
<asp:CustomValidator ID="NoUserValidator" ControlToValidate="UsernameTB" runat="server" ErrorMessage="User Taken!" CssClass="failureNotification" 
      ValidationGroup="RegisterUserValidationGroup"  OnServerValidate="UserValidate">*</asp:CustomValidator>

接下来是函数:

protected void UserValidate(object source, ServerValidateEventArgs args)
    {
        SqlDataSource1.SelectCommand = "SELECT ClientID FROM [Clients] WHERE Username= '" + UserNameTB.Text + "'";
        DataView dv = (DataView)SqlDataSource1.Select(DataSourceSelectArguments.Empty);
        if (dv.Table.Rows.Count != 0)
            args.IsValid = false;
        else
            args.IsValid = true;
    }

按钮:
<asp:Button ID="CreateUserButton" runat="server" CommandName="MoveNext" Text="Create User" 
       ValidationGroup="RegisterUserValidationGroup" 
       onclick="CreateUserButton_Click"/>

问题在于,即使自定义验证函数被调用并设置.IsValid 为false,但按钮的逻辑仍然会运行!

我不确定它是否有价值,但我也尝试设置NoUserValidator.IsValid = false。 - RanH
我在你的标记中没有看到按钮,但请确保它已经设置了ValidationGroup为RegisterUserValidationGroup。 - Gloopy
我将按钮代码添加到了消息中。 - RanH
1个回答

11
在按钮的onclick函数中,添加一个检查以查看页面是否有效。
protected void CreateUserButton_Click(object sender, EventArgs e)
{
    if (Page.IsValid)
    { 
        // Create the user
    }
}

那就这样吧。这是因为您的自定义验证器已设置为在服务器上进行验证,即在回发期间进行验证。代码首先运行验证器代码,在其中设置了标志。接下来在回发堆栈中的是按钮的onclick函数。无论验证函数的结果如何,此函数都将运行,因此在此处需要检查标志的值。这是在服务端验证自定义验证控件时的行为。
另一种选择是在客户端进行验证。如果查看由浏览器生成的页面源代码,则会看到为添加了Javascript。它的行为已知,并且在客户端处理,因此不需要回发来评估表达式并验证页面(所有这些都由javascript处理)。自定义验证器函数未知,因此除非您自己定义客户端验证脚本,否则需要回发。
这里有更多关于MSDN的信息链接。

1
谢谢,问题已解决。您能解释一下为什么其他验证器可以正常工作,而对于自定义的验证器,我需要添加您所写的内容吗? - RanH
1
其实,我不太确定,所以我只是猜测,但我认为这是因为其他验证器在客户端进行验证,而自定义验证器在服务器端进行验证。由于它是在服务器端进行验证,所以回发已经开始,你首先执行自定义验证器,然后才执行按钮的点击函数。这有道理吗? - The Jonas Persson
你的描述很有道理,但我希望页面在所有验证器都通过之前等待,而且除此之外,所有其他验证器也都配置为runat=server,但是也许这对它们没有影响? - RanH
3
它们被设置为runat=server仅意味着服务器生成了它们,并且您可以在代码后端中访问它们。但是,如果您查看浏览器生成的页面源代码,您将看到针对regular expression validator添加了javascripts。它的行为已知,因此不需要回发以评估表达式并验证页面(这都由javascript处理)。自定义验证器功能未知,因此需要回发(除非您在javascript中设置客户端验证脚本)。 - The Jonas Persson
1
谢谢。这真的帮了我很多。你有没有MSDN参考资料?或者其他文章/博客参考资料吗? - LCJ
1
这个链接描述得相当不错:http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.customvalidator(v=vs.80).aspx - The Jonas Persson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接