What determines the order validators fire in?

亡梦爱人 提交于 2019-12-12 15:09:42

问题


I have a webform with two custom validators:

  • One to validate that a string is a date. I don’t care what format, so long as it’s parseable.
  • Another to ensure that one date is equal to or greater than another. I just couldn’t get the compare validator to play nice with any date format.
<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);
}

The problem is that the ValidateStartEndDate validator is firing before the Date_ServerValidate validator, so if the date is not valid, a format exception is thrown on DateTime.Parse. Obviously this validator could check for a valid date before parsing, but I’d really prefer to have a discrete validator with an appropriate message.

So the question is this: what determines the sequence with which the validators fire? Unless I’m missing something, this is not declared at the tag level.


回答1:


You can't count on a certain sequence the validators will fire and also you shouldnt. You have to make sure for yourself that the order is irrelevant.

So you could

  1. check for the valid date simultaneously with the Equal-Greater-Check.
  2. First Call your IsDate-Validator's Validate()-Function and then check if it IsValid
  3. All validators are added to the Page.Validators collection and validation runs through this collection in order. If your logic really should rely on this order: change the order of the validators in the ASPX-Page

Some interesting infos about Page-Validation: http://msdn.microsoft.com/en-us/library/aa479045.aspx




回答2:


Validation control execution order is determined by the order of the controls in the ValidatorCollection returned by Page.Validators. This order is, in turn, determined by the order of the validation controls in the markup, with some exceptions (e.g. validators within data-bound controls will get added to the collection later, and so will be at the end).

If you set CausesValidation=false on your button and then trigger validation manually with Page.Validate, you can use the Add and Remove methods on the ValidatorCollection to change the execution order:

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);
    }
}

Then, later on in the triggering control:

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

    // validation passed, proceed...
}

Disclaimer: all of this is empirical, I haven't found MSDN docs to back it up, but it seems to work.



来源:https://stackoverflow.com/questions/3252722/what-determines-the-order-validators-fire-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!