ASP.NET自定义验证器不对文本框进行触发

30

我有一个文本框,同时设置了必填字段验证器和自定义验证器。 必填字段验证器能够正常触发,但是我无法使自定义验证器正常触发?

<asp:TextBox ID="txtPRI" runat="server" Width="295" /><br />

<asp:RequiredFieldValidator display="Dynamic" CssClass="leftAlign" SetFocusOnError="true"  runat="server" controltovalidate="txtPRI" errormessage="Please enter your PRI" />

 <asp:CustomValidator runat="server" id="cusCustom" controltovalidate="txtPRI" onservervalidate="cusCustom_ServerValidate" Enabled="true" ValidateEmptyText="true" display="Dynamic" CssClass="leftAlign" SetFocusOnError="true"  errormessage="The text must be exactly 8 characters long!" />

代码后台

protected void cusCustom_ServerValidate(object sender, ServerValidateEventArgs e)
    {
        Response.Write("firing - test");
        Response.End();


        if (e.Value.Length == 8)
            e.IsValid = true;
        else
            e.IsValid = false;
    }

1
我也很想知道这个答案。 - jonezy
这个方法有被触发吗?你是否将它设置为验证控件的OnServerValidate事件?你能给我们展示一下验证控件的ASPX标签吗? - Justin Morgan
5
请注意客户端验证器——它们很容易被欺骗,提交恶意数据。请务必在服务器上进行输入验证。以某种方式确保验证输入的有效性。 - Andrey
这是一个棘手的问题。仅用于测试目的,在Page_Load或其他你知道会被触发的地方放置Page.Validate()和/或cusCustom.Validate()。然后逐步执行并观察它是否被触发。我有一种感觉事件没有注册,尽管从你的代码看起来像是注册了。顺便问一下,这是哪个版本的ASP.NET? - Justin Morgan
@Eric:我的评论是回应@jonezy的。 - Andrey
显示剩余2条评论
8个回答

53

请检查您的CustomValidator属性ValidateEmptyText是否设置为true,以便验证空文本。然后您将不再需要RequiredFieldValidator

编辑:我拿了您的代码并将其复制粘贴到一个空项目中,它按预期工作。可能有些您没有发布或发布不正确的内容我们不知道。是否还有其他影响触发验证按钮或验证控件本身的内容?

编辑:这是确切的代码(在内容页中):

aspx页面:

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <asp:TextBox ID="txtPRI" runat="server" Width="295" /><br />
    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" display="Dynamic" CssClass="leftAlign" SetFocusOnError="true"  runat="server" controltovalidate="txtPRI" errormessage="Please enter your PRI" />  
    <asp:CustomValidator runat="server" id="cusCustom" controltovalidate="txtPRI" onservervalidate="cusCustom_ServerValidate" Enabled="true" ValidateEmptyText="true" display="Dynamic" CssClass="leftAlign" SetFocusOnError="true"  errormessage="The text must be exactly 8 characters long!" /> 
</asp:Content>

.cs页面(空的Page_Load):

protected void cusCustom_ServerValidate(object sender, ServerValidateEventArgs e)
{ 
    // put a break point here and it stops on it
    if (e.Value.Length == 8)
        e.IsValid = true;
    else
        e.IsValid = false;
} 

真的,我的代码中某些东西正在干扰事件的触发。我有一些其他文本框的必填字段验证器,这就是全部。它们都可以正常触发吗? - Eric Savard
1
@Eric Savard 你可以进行一个简单的测试,只需将你发布的代码复制并粘贴到一个空项目中。它可以正常工作。你需要隔离出引起问题的原因,我建议你从尽可能多地注释掉代码开始,并使其正常工作,然后逐步添加回来以确定哪个片段导致了问题。 - Kelsey
Kesley,请你把代码发给我。因为我按照你用一个新的网页表单所做的一切,它仍然无法正常工作。 - Eric Savard
<form id="form1" runat="server"> <div> <div class="floatLeft width35"><span class="red">*</span><asp:Label ID="Label3" runat="server" Text="PRI (8 characters):" /></div><div class="rightarm"><asp:TextBox ID="txtPRI" runat="server" Width="295" /><br /> <asp:CustomValidator runat="server" id="cusCustom" controltovalidate="txtPRI" onservervalidate="cusCustom_ServerValidate" Enabled="true" ValidateEmptyText="true" display="Dynamic" CssClass="leftAlign" SetFocusOnError="true" errormessage="The text must be exactly 8 characters long!" /></div> </div> </form> - Eric Savard
@EricSavard - 也许我评论得太晚了。但是有时候需要设置FieldRequired="True",否则它会表现得很奇怪。 - Akshay Anand
哇,真是太棒了...谢谢你,你救了我一天...该死的微软和你们的验证器... - Edgar J. Rodriguez

19

好的...这是一个没有被采纳答案的旧问题,而我刚好遇到了同样的问题。

所以我想为任何可能遇到此问题并需要答案的人提供解决方法...

如果您正在进行常规验证以及自定义服务器验证,那么自定义服务器验证只会在所有其他验证都通过的情况下触发,至少对我来说是这样的。


1
谢谢,这就是我的原因。 - Fiona - myaccessible.website
1
旧帖子,但无论如何感谢您的回复。这回答了我的问题 :) - japesu

9

记得在 CustomValidator 上设置此属性...

ValidateEmptyText="True"

5
除了上面的建议外,我发现在较新版本的.Net框架中,您必须显式地在服务器上触发validate()方法,以获得自定义验证程序。
    // validate page before allowing import to go through
    Page.Validate();
    if (!Page.IsValid)
        return;

4
我也遇到了这个问题。是的,在CustomValidator触发之前,所有其他验证器都必须通过。
但是,如果这对您不起作用,则可能需要使用Page.Validate()强制验证您特定的验证组
这就是我所做的,我仍然设有RequiredFieldValidator,而且不需要ValidateEmptyText="true"
在文本框中添加一个陷阱以强制进行验证。
<asp:TextBox ID="txtLeft" runat="server" Width="110px" TextMode="SingleLine" style="text-align:center" OnTextChanged="TextBoxChanged_DateTimeTest" AutoPostBack="True" ValidationGroup="vg2"></asp:TextBox>

请注意,我正在使用一个特定的“验证组”“vg2”,因为我有其他区域不想进行验证。
另外,我想要验证日期和时间!
还需要两件事。TextBoxChanged_DateTimeTest方法...
protected void TextBoxChanged_DateTimeTest(object sender, EventArgs e)
    {
        Page.Validate("vg2");
        if (!Page.IsValid)
        {
            TextBox tb1 = (TextBox)sender;
            IFormatProvider culture = new CultureInfo("en-AU", true);

            //if page is not valid, then validate the date here and default it to today's date & time, 
            String[] formats = { "dd MM yyyy HH:mm", "dd/MM/yyyy HH:mm", "dd-MM-yyyy HH:mm" };
            DateTime dt1;
            DateTime.TryParseExact(tb1.Text, formats, culture, DateTimeStyles.AdjustToUniversal, out dt1);
            if (dt1.ToShortDateString() != "1/01/0001")
                tb1.Text = dt1.ToShortDateString() + " " + dt1.ToShortTimeString();
            else
                tb1.Text = DateTime.Today.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();
        }
    }

您还需要为CustomValidator进行服务器端验证。在我的情况下,文本框必须接受日期和时间!

以下是标记...

<asp:CustomValidator ID="CustomValidator3" runat="server" ControlToValidate="txtLeft" ErrorMessage="Invalid date & time format (dd/MM/yyyy HH:mm)" 
                                    SetFocusOnError="true" ValidationGroup="vg2" OnServerValidate="CustomValidator_DateTime"></asp:CustomValidator>

下面是这段代码的实现...

protected void TextBoxChanged_DateTimeTest(object sender, EventArgs e)
{
    Page.Validate("vg2");
    if (!Page.IsValid)
    {
        TextBox tb1 = (TextBox)sender;
        IFormatProvider culture = new CultureInfo("en-AU", true);

        //if page is not valid, then validate the date here and default it to today's date & time, 
        String[] formats = { "dd MM yyyy HH:mm", "dd/MM/yyyy HH:mm", "dd-MM-yyyy HH:mm" };
        DateTime dt1;
        DateTime.TryParseExact(tb1.Text, formats, culture, DateTimeStyles.AdjustToUniversal, out dt1);
        if (dt1.ToShortDateString() != "1/01/0001")
            tb1.Text = dt1.ToShortDateString() + " " + dt1.ToShortTimeString();
        else
            tb1.Text = DateTime.Today.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();
    }
}

祝你好运!


1
问题在于您正在调用Response.End(),这实际上会停止页面的所有执行。因此,if/else块根本没有运行。请在调试时注释掉该行或跳过它,然后验证器将按预期触发。
我建议您使用调试器而不是以这种方式编写响应,或者如果选择使用它,请注意Response.End()的后果。

是的,我听到你说的话,但我只是想确保处理程序被触发了,而它并没有被触发。 - Eric Savard
@Eric,你尝试过将那些Response行注释掉并运行吗?当我这样做时,它对我来说很好用。 - Ahmad Mageed
@Eric:我也认为这是问题所在。你说方法没有触发;你是否在此行之前设置了断点并逐步验证过? - Justin Morgan
真的啊,对我一点用都没有.. 这意味着有其他东西在干扰它。 - Eric Savard
Justin,是的,我设置了断点,但它肯定没有触发。 - Eric Savard

1
据我所记,如果您的文本框为空,自定义验证器将不会触发。

6
如果设置了ValidateEmptyText属性为true,则CustomValidator可以在文本为空时触发,正如我在答案中所述。这应该也能够满足他对于RequiredFieldValidator的需求。 - Kelsey

0
如果您的代码有多个部分,并且每个部分都有一些验证器,请为每个部分创建一个validateGroup。

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