RequiredFieldValidators на стороне сервера не работают - PullRequest
1 голос
/ 07 марта 2011

У меня есть форма, представляющая опрос, который динамически генерируется на основе некоторой конфигурации базы данных. У меня есть пользовательский серверный элемент управления для рендеринга опроса (SurveyRenderer), который содержит пользовательские серверные элементы управления для рендеринга вопросов (QuestionRenderers). Я динамически добавляю RequiredFieldValidators к вопросам, если они помечены как обязательные. Я добавляю эти валидаторы в коллекцию элементов управления SurveyRenderer.

Суть кода ...

// In SurveyRenderer.CreateChildControls()...
foreach (QuestionRenderer questionRenderer in questionRenderers)
{
   if (questionRenderer.Question.IsRequired)
   {
       Controls.Add(CreateRequiredValidator(questionRenderer));
   }
}

Проверка на стороне клиента работает нормально - если кто-то пропустил требуемый вопрос, валидаторы его улавливают, а форма не проверяет. Однако, если я отключаю JavaScript и отправляю неверную форму, валидаторы, похоже, не работают.

На стороне сервера я звоню Page.Validate() и проверяю Page.IsValid в обработчике событий нажатия кнопки отправки. Несмотря на отправку формы, где необходимые вопросы были оставлены пустыми - что-то, что было бы обнаружено клиентом - на стороне сервера Page.IsValid остается True.

// In SurveyPage.aspx...
public void btnSubmit_Click(object sender, EventArgs e)
{
   Page.Validate();
   if (Page.IsValid)
   {
       // Always get here, even though the form is not valid and would
       // have been caught client-side...
   }
}

Должен ли я добавлять валидаторы в коллекцию Control Page, а не SurveyRenderer? Почему это работает на стороне клиента, но не на стороне сервера?

ОБНОВЛЕНИЕ : Мой QuestionRenderer помечен:

[ValidationProperty("IsValid")]

И метод get IsValid выглядит так:

// QuestionRenderer.IsValid
public bool IsValid
{
    get
    {
        EnsureChildControls();
        if (Question.IsRequired && QuestionIsNotAnswered())
        {
            return false;
        }

        return true;
    }
}

Если я установлю точку останова и сделаю шаг, я увижу, что QuestionRenderer.IsValid срабатывает в порядке. Он возвращает false, когда должен это сделать. Если я ухожу и звоню в btn_submitClick:

// In SurveyPage.aspx...
public void btnSubmit_Click(object sender, EventArgs e)
{
    foreach (IValidator validator in Page.Validators)
    {
        validator.Validate();  // this calls through to QuestionRenderer.IsValid, which returns false...
        bool valIsValid = validator.IsValid; // yet this is set to True
    }
}

Таким образом, validator.IsValid имеет значение true, хотя при вызове QuestionRenderer.IsValid возвращается значение false. Так что, возможно, я не правильно подключил что-то? Использование [ValidationProperty("IsValid")] недостаточно?

1 Ответ

1 голос
/ 07 марта 2011

На самом деле, валидация использует Page.Validators, где хранятся все валидаторы (фактическая процедура довольно хитрая), поэтому не имеет значения, где вы их добавляете.

источник BaseValidator

protected internal override void OnInit(EventArgs e)
{
    base.OnInit(e);
    this.Page.Validators.Add(this);
}

я бы оставил их на виду, так как вы можете использовать object sender -параметр (который представляет валидатор), чтобы получить связанный элемент управления ...

Я полагаю, ваш CreateChildControls - который выполняет присоединение валидаторов - вызывается поздно, поэтому он пропускает фазу валидации ... не могли бы вы попытаться позвонить EnsureChildControls в OnLoad -event, чтобы посмотреть, что-то изменится? еще один шанс, что ваши валидаторы не видны или отключены ...

EDIT

в соответствии с вашими правками я бы рекомендовал вам использовать CustomValidator - RequiredFieldValidator будет возвращать true в каждом случае (свойство true или false), потому что оно не пустое :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...