Что определяет порядок срабатывания валидаторов?

У меня есть веб-форма с двумя настраиваемыми валидаторами:

  • Один для подтверждения того, что строка является датой. Меня не волнует, в каком формате, если он разбирается.
  • Другой, чтобы гарантировать, что одна дата равна или больше другой. Я просто не мог заставить валидатор сравнения нормально работать с любым форматом даты.
<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 выдается исключение формата. Очевидно, этот валидатор может проверять действительную дату перед синтаксическим анализом, но я действительно предпочел бы иметь дискретный валидатор с соответствующим сообщением.

Итак, вопрос заключается в следующем: что определяет последовательность срабатывания валидаторов? Если я чего-то не упускаю, это не объявляется на уровне тега.


person Troy Hunt    schedule 15.07.2010    source источник


Ответы (2)


Вы не можете рассчитывать на определенную последовательность, срабатывающую валидаторы, и не должны. Вы должны сами убедиться, что порядок не актуален.

Чтобы ты мог

  1. проверьте действительную дату одновременно с проверкой Equal-Greater-Check.
  2. Сначала вызовите Validate () - функцию IsDate-Validator, а затем проверьте, является ли она IsValid
  3. Все валидаторы добавляются в коллекцию Page.Validators, и проверка проходит через эту коллекцию по порядку. Если ваша логика действительно должна полагаться на этот порядок: измените порядок валидаторов на странице ASPX

Некоторая интересная информация о проверке страниц: http://msdn.microsoft.com/en-us/library/aa479045.aspx

person Tim Schmelter    schedule 15.07.2010
comment
Спасибо, Тим, я выбрал вариант 2 и принял твой ответ. Сказав это, я все еще не уверен, что определяет последовательность. Это НЕ порядок, в котором они указаны на странице, иначе у меня не было бы этой проблемы. Тем не менее, теперь это работает, так что любопытство в сторону, я счастлив. Спасибо! - person Troy Hunt; 19.07.2010

Порядок выполнения элементов управления проверки определяется порядком элементов управления в ValidatorCollection, возвращенный _2 _ . Этот порядок, в свою очередь, определяется порядком элементов управления валидацией в разметке с некоторыми исключениями (например, валидаторы в элементах управления с привязкой к данным будут добавлены в коллекцию позже, и так будет в конце).

Если вы установите CausesValidation=false на своей кнопке, а затем активируете проверку вручную с помощью Page.Validate, вы можете использовать методы Add и Remove на ValidatorCollection, чтобы изменить порядок выполнения:

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, чтобы сделать резервную копию, но, похоже, это работает.

person Evan Haas    schedule 09.06.2014