ASP.Net CustomValidator в CompositeControl - PullRequest
2 голосов
/ 30 июля 2009

Я представляю вам небольшую загадку ... следующий элемент управления не должен проверяться каждый раз, несмотря ни на что, но это не так:

public class Test : CompositeControl
{
    protected override void CreateChildControls()
    {
        Controls.Clear();
        CreateControlHierachy();
        ClearChildViewState();
    }

    void CreateControlHierachy()
    {
        var validator = new CustomValidator
        {
            ErrorMessage = "Can't do that!"
        };

        validator.ServerValidate += (sender, e) =>
        {
            e.IsValid = false;
        };

        Controls.Add(validator);
    }
}

Чтобы «исправить» проблему, добавьте следующую строку в CreateControlHierachy и все работает как положено:

Controls.Add(new TextBox());

Элемент управления зарегистрирован в web.config и размещен на простой странице, подобной этой:

<uc:Test runat="server" />

Использование отладчика в событии обратной отправки показывает следующее:

  • Валидатор находится в иерархии управления на странице, как и ожидалось.
  • Валидаторы не зарегистрированы в Page.Validators.
  • И Page.IsValid, и validator.IsValid по-прежнему имеют значение true.

Какое влияние оказывает TextBox на валидатор и как правильно это исправить?

1 Ответ

1 голос
/ 31 июля 2009

Я нашел возможное объяснение этому. Наличие TextBox добавляет дочерний элемент управления к вашему элементу управления, который является IPostbackDataHandler. Чтобы загрузить данные поста, страница должна сначала найти элемент управления, который, конечно, делает это, вызывая FindControl. Когда FindControl делает свое дело, он в конечном итоге получает доступ к коллекции Controls вашего элемента управления. Поскольку ваш элемент управления является CompositeControl, он вызывает EnsureChildControls, который вызывает CreateChildControls.

Все это происходит до санкционирования. Извлеките TextBox, и коллекция Controls больше не будет доступна до проверки, и, следовательно, валидатор не будет создан до окончания проверки (скорее всего, во время предварительного представления)

Поскольку ваш валидатор не существует на этапе валидации, он не вызывается. Я рекомендую добавить вызов EnsureChildControls до того, как произойдет проверка.

    protected override void OnLoad(EventArgs e)
    {
        EnsureChildControls();
        base.OnLoad(e);
    }
...