【问题标题】:What determines the order validators fire in?什么决定了验证器触发的顺序?
【发布时间】:2011-03-16 05:28:10
【问题描述】:

我有一个带有两个自定义验证器的网络表单:

  • 用于验证字符串是否为日期。我不在乎什么格式,只要它是可解析的。
  • 另一个确保一个日期等于或大于另一个。我只是无法让比较验证器与任何日期格式配合使用。
<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 上引发格式异常。显然,这个验证器可以在解析之前检查一个有效的日期,但我真的更喜欢有一个带有适当消息的离散验证器。

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

【问题讨论】:

    标签: asp.net validation customvalidator


    【解决方案1】:

    你不能指望验证器会触发的特定顺序,你也不应该指望它。您必须自己确保订单无关紧要。

    所以你可以

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

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

    【讨论】:

    • 谢谢蒂姆,我选择了选项 2 并接受了您的回答。话虽如此,我仍然不确定是什么决定了顺序。这不是他们在页面上声明的顺序,否则我不会有这个问题。尽管如此,它现在仍然有效,所以抛开好奇心,我很高兴。谢谢!
    【解决方案2】:

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

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

    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 文档来支持它,但它似乎有效。

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 2016-02-16
      • 1970-01-01
      • 2011-03-21
      • 2016-02-15
      相关资源
      最近更新 更多