是什么决定了订单验证员的火力?

时间:2010-07-15 05:33:47

标签: asp.net validation customvalidator

我有一个带有两个自定义验证器的webform:

  • 验证字符串是否为日期。我不在乎什么格式,只要它是可解析的。
  • 另一个确保一个日期等于或大于另一个日期。我无法让比较验证器与任何日期格式都很好。
<asp:TextBox ID="txtResourceStartDate" runat="server"
    CssClass="textBox mandatory dateField" />
<asp:CustomValidator ID="valResourceStartDateIsDate" runat="server"
    ControlToValidate="txtResourceStartDate" Display="None"
    ErrorMessage="Start date must be a valid date"
    OnServerValidate="Date_ServerValidate" />

<asp:TextBox ID="txtResourceEndDate" runat="server"
    CssClass="textBox mandatory dateField" />
<asp:CustomValidator ID="valResourceEndDateIsDate" runat="server"
    ControlToValidate="txtResourceEndDate" Display="None"
    ErrorMessage="End date must be a valid date"
    OnServerValidate="Date_ServerValidate" />

<asp:CustomValidator Display="None" Text="" ID="valForStartEndDate" runat="server"
    OnServerValidate="ValidateStartEndDate"
    ErrorMessage="Last day must be greater than or equal to first day" />
protected void Date_ServerValidate(object source, ServerValidateEventArgs args)
{
    DateTime outDate;
    args.IsValid = DateTime.TryParse(args.Value, out outDate);
}

protected void ValidateStartEndDate(object sender, ServerValidateEventArgs e)
{
    e.IsValid = DateTime.Parse(txtResourceEndDate.Text) >=
                DateTime.Parse(txtResourceStartDate.Text);
}

问题是ValidateStartEndDate验证器在Date_ServerValidate验证器之前触发,因此如果日期无效,则会在DateTime.Parse上抛出格式异常。显然,这个验证器可以在解析之前检查一个有效的日期,但我真的更喜欢有一个带有适当消息的离散验证器。

所以问题是:确定验证器触发的顺序是什么?除非我遗漏了某些东西,否则不会在标记级别声明。

2 个答案:

答案 0 :(得分:1)

您不能指望验证器会触发某个序列,也不应该。你必须确保订单无关紧要。

所以你可以

  1. 检查有效日期 同时与 相等大检查。
  2. 首先调用IsDate-Validator的Validate() - 函数,然后检查它是否为IsValid
  3. 所有验证器都会添加到Page.Validators集合中,并按顺序通过此集合运行验证。如果您的逻辑真的应该依赖于此顺序:更改ASPX-Page
  4. 中验证程序的顺序

    有关页面验证的一些有趣信息:http://msdn.microsoft.com/en-us/library/aa479045.aspx

答案 1 :(得分:0)

验证控制执行顺序由ValidatorCollection返回的Page.Validators中的控件顺序决定。反过来,此顺序由标记中的验证控件的顺序决定,但有一些例外(例如,数据绑定控件中的验证器将在稍后添加到集合中,因此将在结束时添加)。

如果您在按钮上设置CausesValidation=false,然后使用Page.Validate手动触发验证,则可以使用Add上的RemoveValidatorCollection方法更改执行顺序:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) {
        // move myValidator to the very end, so it executes last
        Validators.Remove(myValidator);
        Validators.Add(myValidator);
    }
}

然后,稍后在触发控件中:

protected void myButton_Click(object sender, EventArgs e)
{
    Page.Validate();
    if (!Page.IsValid) { return; }

    // validation passed, proceed...
}

免责声明:所有这些都是经验性的,我还没有找到MSDN文档进行备份,但它似乎有效。